{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "36d40b101adfe75",
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T08:46:33.672160Z",
     "start_time": "2025-03-06T08:46:33.662783Z"
    }
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "\n",
    "sys.path.append(r'E:\\PycharmProjects\\risk-management')\n",
    "\n",
    "# 导入自定义模块，支持模型训练、预测、评估等功能\n",
    "from rmtools.utils import intnx\n",
    "import warnings\n",
    "\n",
    "import pandas as pd\n",
    "import statsmodels.api as sm\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from rmtools.stats.stats import stats_max_corr, stats_max_vif\n",
    "from tqdm import tqdm\n",
    "\n",
    "# 调整pandas显示格式，保留两位小数，并使用千分位分隔符\n",
    "pd.options.display.float_format = '{:.2f}'.format\n",
    "\n",
    "warnings.filterwarnings(\"ignore\", category=FutureWarning)\n",
    "warnings.filterwarnings('ignore', category=UserWarning)\n",
    "\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "plt.rcParams['axes.unicode_minus'] = False"
   ]
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "            NPL  M0000541  M0039354  M5650805  M5525763  M5525764  M0001385  \\\nDate                                                                          \n2000-03-31  NaN      8.70      8.70       NaN       NaN       NaN     13.74   \n2000-06-30  NaN      8.90      9.10       NaN       NaN       NaN     14.29   \n2000-09-30  NaN      8.90      8.80       NaN       NaN       NaN     15.21   \n2000-12-31  NaN      8.49      7.50       NaN       NaN       NaN     14.45   \n2001-03-31  NaN      9.50      9.50       NaN       NaN       NaN     15.06   \n...         ...       ...       ...       ...       ...       ...       ...   \n2023-12-31 0.03      5.25      5.20      5.03      9.40     10.60     10.00   \n2024-03-31 0.03      5.30      5.30      5.23      9.07      9.67      8.57   \n2024-06-30 0.03      5.00      4.70      5.00      8.27      8.77      6.80   \n2024-09-30 0.03      4.80      4.60      5.20      8.10      8.07      6.47   \n2024-12-31 0.03      5.00      5.40      5.03      7.87      7.43      7.30   \n\n            M0001383  M0000609  M0000607  M0001428  M0000273  M0001227  \\\nDate                                                                     \n2000-03-31     17.80     44.07     39.33     10.37      8.50      1.03   \n2000-06-30     22.57     32.30     37.80      9.83     12.10      2.07   \n2000-09-30     21.77     43.47     25.00      9.33     12.90      4.04   \n2000-12-31     17.10     29.43     15.70      9.30      9.70      3.30   \n2001-03-31     16.87     18.07     14.27     10.20     15.10      0.84   \n...              ...       ...       ...       ...       ...       ...   \n2023-12-31      1.50      0.92     -1.26      8.37      3.00     -2.77   \n2024-03-31      2.73      1.93      2.03      4.30      4.50     -2.67   \n2024-06-30     -3.53      2.70      5.67      2.67      3.90     -1.57   \n2024-09-30     -7.10      2.47      6.03      2.67      3.40     -1.80   \n2024-12-31     -3.73     -1.73     10.03      3.83      3.20     -2.57   \n\n            M0000612  M0000545  NPL_logit  \nDate                                       \n2000-03-31      0.10     10.93        NaN  \n2000-06-30      0.10     11.70        NaN  \n2000-09-30      0.27     12.53        NaN  \n2000-12-31      0.93     10.80        NaN  \n2001-03-31      0.67     11.13        NaN  \n...              ...       ...        ...  \n2023-12-31     -0.33      6.00      -3.39  \n2024-03-31     -0.00      6.03      -3.48  \n2024-06-30      0.27      5.87      -3.43  \n2024-09-30      0.50      5.00      -3.53  \n2024-12-31      0.20      5.63      -3.59  \n\n[100 rows x 16 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>NPL</th>\n      <th>M0000541</th>\n      <th>M0039354</th>\n      <th>M5650805</th>\n      <th>M5525763</th>\n      <th>M5525764</th>\n      <th>M0001385</th>\n      <th>M0001383</th>\n      <th>M0000609</th>\n      <th>M0000607</th>\n      <th>M0001428</th>\n      <th>M0000273</th>\n      <th>M0001227</th>\n      <th>M0000612</th>\n      <th>M0000545</th>\n      <th>NPL_logit</th>\n    </tr>\n    <tr>\n      <th>Date</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2000-03-31</th>\n      <td>NaN</td>\n      <td>8.70</td>\n      <td>8.70</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>13.74</td>\n      <td>17.80</td>\n      <td>44.07</td>\n      <td>39.33</td>\n      <td>10.37</td>\n      <td>8.50</td>\n      <td>1.03</td>\n      <td>0.10</td>\n      <td>10.93</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>2000-06-30</th>\n      <td>NaN</td>\n      <td>8.90</td>\n      <td>9.10</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>14.29</td>\n      <td>22.57</td>\n      <td>32.30</td>\n      <td>37.80</td>\n      <td>9.83</td>\n      <td>12.10</td>\n      <td>2.07</td>\n      <td>0.10</td>\n      <td>11.70</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>2000-09-30</th>\n      <td>NaN</td>\n      <td>8.90</td>\n      <td>8.80</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>15.21</td>\n      <td>21.77</td>\n      <td>43.47</td>\n      <td>25.00</td>\n      <td>9.33</td>\n      <td>12.90</td>\n      <td>4.04</td>\n      <td>0.27</td>\n      <td>12.53</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>2000-12-31</th>\n      <td>NaN</td>\n      <td>8.49</td>\n      <td>7.50</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>14.45</td>\n      <td>17.10</td>\n      <td>29.43</td>\n      <td>15.70</td>\n      <td>9.30</td>\n      <td>9.70</td>\n      <td>3.30</td>\n      <td>0.93</td>\n      <td>10.80</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>2001-03-31</th>\n      <td>NaN</td>\n      <td>9.50</td>\n      <td>9.50</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>15.06</td>\n      <td>16.87</td>\n      <td>18.07</td>\n      <td>14.27</td>\n      <td>10.20</td>\n      <td>15.10</td>\n      <td>0.84</td>\n      <td>0.67</td>\n      <td>11.13</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>2023-12-31</th>\n      <td>0.03</td>\n      <td>5.25</td>\n      <td>5.20</td>\n      <td>5.03</td>\n      <td>9.40</td>\n      <td>10.60</td>\n      <td>10.00</td>\n      <td>1.50</td>\n      <td>0.92</td>\n      <td>-1.26</td>\n      <td>8.37</td>\n      <td>3.00</td>\n      <td>-2.77</td>\n      <td>-0.33</td>\n      <td>6.00</td>\n      <td>-3.39</td>\n    </tr>\n    <tr>\n      <th>2024-03-31</th>\n      <td>0.03</td>\n      <td>5.30</td>\n      <td>5.30</td>\n      <td>5.23</td>\n      <td>9.07</td>\n      <td>9.67</td>\n      <td>8.57</td>\n      <td>2.73</td>\n      <td>1.93</td>\n      <td>2.03</td>\n      <td>4.30</td>\n      <td>4.50</td>\n      <td>-2.67</td>\n      <td>-0.00</td>\n      <td>6.03</td>\n      <td>-3.48</td>\n    </tr>\n    <tr>\n      <th>2024-06-30</th>\n      <td>0.03</td>\n      <td>5.00</td>\n      <td>4.70</td>\n      <td>5.00</td>\n      <td>8.27</td>\n      <td>8.77</td>\n      <td>6.80</td>\n      <td>-3.53</td>\n      <td>2.70</td>\n      <td>5.67</td>\n      <td>2.67</td>\n      <td>3.90</td>\n      <td>-1.57</td>\n      <td>0.27</td>\n      <td>5.87</td>\n      <td>-3.43</td>\n    </tr>\n    <tr>\n      <th>2024-09-30</th>\n      <td>0.03</td>\n      <td>4.80</td>\n      <td>4.60</td>\n      <td>5.20</td>\n      <td>8.10</td>\n      <td>8.07</td>\n      <td>6.47</td>\n      <td>-7.10</td>\n      <td>2.47</td>\n      <td>6.03</td>\n      <td>2.67</td>\n      <td>3.40</td>\n      <td>-1.80</td>\n      <td>0.50</td>\n      <td>5.00</td>\n      <td>-3.53</td>\n    </tr>\n    <tr>\n      <th>2024-12-31</th>\n      <td>0.03</td>\n      <td>5.00</td>\n      <td>5.40</td>\n      <td>5.03</td>\n      <td>7.87</td>\n      <td>7.43</td>\n      <td>7.30</td>\n      <td>-3.73</td>\n      <td>-1.73</td>\n      <td>10.03</td>\n      <td>3.83</td>\n      <td>3.20</td>\n      <td>-2.57</td>\n      <td>0.20</td>\n      <td>5.63</td>\n      <td>-3.59</td>\n    </tr>\n  </tbody>\n</table>\n<p>100 rows × 16 columns</p>\n</div>"
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "file_path = r'E:\\Psbc\\03.组合风险\\02.ECL\\202503 例行更新参数\\中邮消费金融有限公司预期信用损失法实施方案参数更新（2025年3月版)_工作底稿.xlsx'\n",
    "# 季末处理的指标清单\n",
    "x_qe_list: list = ['M0000541', 'M0000273']\n",
    "\n",
    "data_raw = pd.read_excel(file_path, sheet_name='原始数据', index_col=0)\n",
    "data_raw.index = pd.to_datetime(pd.to_datetime(data_raw.index).astype(str).map(lambda x: intnx(x, 'm', 0, 'e')))\n",
    "data_model_sample = data_raw.resample('QE').mean()\n",
    "data_model_sample[x_qe_list] = data_raw[x_qe_list].resample('QE').last()\n",
    "data_model_sample['NPL_logit'] = np.log(data_model_sample['NPL'] / (1 - data_model_sample['NPL']))\n",
    "\n",
    "data_model_sample.to_clipboard()\n",
    "data_model_sample"
   ],
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-03-06T08:46:34.540151Z",
     "start_time": "2025-03-06T08:46:34.323318Z"
    }
   },
   "id": "initial_id",
   "execution_count": 7
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "            NPL  M0000541  M0039354  M5650805  M5525763  M5525764  M0001385  \\\nDate                                                                          \n2017-03-31 0.00      7.00      7.00      5.01     16.17     12.78     10.40   \n2017-06-30 0.00      7.00      7.00      5.01     15.31     13.12      9.33   \n2017-09-30 0.01      7.00      6.90      5.01     15.18     13.61      8.83   \n2017-12-31 0.01      6.95      6.80      5.01     14.51     13.45      8.70   \n2018-03-31 0.01      6.90      6.90      5.01     13.17     13.07      8.53   \n2018-06-30 0.02      6.90      6.90      4.83     12.20     12.71      8.20   \n2018-09-30 0.02      6.80      6.70      5.00     11.40     12.95      8.33   \n2018-12-31 0.03      6.75      6.50      4.87     10.45     13.02      8.03   \n2019-03-31 0.03      6.30      6.30      5.20     10.89     13.57      8.33   \n2019-06-30 0.03      6.10      6.00      5.03     11.01     13.40      8.50   \n2019-09-30 0.03      6.00      5.90      5.23     10.73     12.69      8.23   \n2019-12-31 0.03      5.95      5.80      5.13     10.65     12.53      8.43   \n2020-03-31 0.03     -6.90     -6.90      5.80     10.97     12.33      9.10   \n2020-06-30 0.04     -1.70      3.10      5.87     12.43     13.23     11.10   \n2020-09-30 0.04      0.60      4.80      5.57     13.23     13.27     10.67   \n2020-12-31 0.03      2.24      6.40      5.23     13.53     13.27     10.43   \n2021-03-31 0.03     18.70     18.70      5.40     12.87     13.20      9.63   \n2021-06-30 0.02     13.00      8.30      5.03     11.23     12.60      8.33   \n2021-09-30 0.02     10.10      5.20      5.03     10.33     12.20      8.27   \n2021-12-31 0.02      8.45      4.30      5.00     10.13     11.80      8.73   \n2022-03-31 0.03      4.80      4.80      5.53     10.40     11.37      9.57   \n2022-06-30 0.04      2.50      0.40      5.83     10.50     10.90     11.00   \n2022-09-30 0.04      3.00      3.90      5.40     10.60     10.93     12.10   \n2022-12-31 0.03      2.95      2.90      5.57      9.97     10.87     12.00   \n2023-03-31 0.03      4.50      4.50      5.47      9.77     11.43     12.73   \n2023-06-30 0.03      5.50      6.30      5.20      9.50     11.40     11.77   \n2023-09-30 0.03      5.20      4.90      5.17      8.97     10.87     10.53   \n2023-12-31 0.03      5.25      5.20      5.03      9.40     10.60     10.00   \n2024-03-31 0.03      5.30      5.30      5.23      9.07      9.67      8.57   \n2024-06-30 0.03      5.00      4.70      5.00      8.27      8.77      6.80   \n2024-09-30 0.03      4.80      4.60      5.20      8.10      8.07      6.47   \n2024-12-31 0.03      5.00      5.40      5.03      7.87      7.43      7.30   \n\n            M0001383  M0000609  M0000607  ...  M0001385_lag4  M0001383_lag4  \\\nDate                                      ...                                 \n2017-03-31     18.23     25.30      6.55  ...          13.57          19.37   \n2017-06-30     16.83     14.11      8.18  ...          12.13          23.73   \n2017-09-30     14.43     14.82      6.38  ...          11.03          25.13   \n2017-12-31     12.50     13.37      9.50  ...          11.43          22.67   \n2018-03-31     10.20     19.68     17.06  ...          10.40          18.23   \n2018-06-30      6.60     20.74     11.50  ...           9.33          16.83   \n2018-09-30      4.33     20.66     11.67  ...           8.83          14.43   \n2018-12-31      1.90      5.18      4.53  ...           8.70          12.50   \n2019-03-31      2.33     -4.09      0.88  ...           8.53          10.20   \n2019-06-30      3.57     -3.49     -1.01  ...           8.20           6.60   \n2019-09-30      3.30     -6.20     -0.24  ...           8.33           4.33   \n2019-12-31      3.73      3.85      1.98  ...           8.03           1.90   \n2020-03-31      3.27     -2.15    -16.81  ...           8.33           2.33   \n2020-06-30      6.27     -9.09     -0.09  ...           8.50           3.57   \n2020-09-30      7.67      3.73      8.41  ...           8.23           3.30   \n2020-12-31      9.23      5.66     16.50  ...           8.43           3.73   \n2021-03-31      9.73     28.93     69.69  ...           9.10           3.27   \n2021-06-30      5.93     44.51     30.37  ...          11.10           6.27   \n2021-09-30      4.27     25.78     23.85  ...          10.67           7.67   \n2021-12-31      3.10     23.68     22.90  ...          10.43           9.23   \n2022-03-31      2.50     10.87     13.76  ...           9.63           9.73   \n2022-06-30      5.17      1.01     11.02  ...           8.33           5.93   \n2022-09-30      6.40      0.07      8.91  ...           8.27           4.27   \n2022-12-31      4.70     -6.66     -8.27  ...           8.73           3.10   \n2023-03-31      5.87     -6.28     -1.35  ...           9.57           2.50   \n2023-06-30      4.37     -7.06     -4.28  ...          11.00           5.17   \n2023-09-30      2.20     -8.53     -9.89  ...          12.10           6.40   \n2023-12-31      1.50      0.92     -1.26  ...          12.00           4.70   \n2024-03-31      2.73      1.93      2.03  ...          12.73           5.87   \n2024-06-30     -3.53      2.70      5.67  ...          11.77           4.37   \n2024-09-30     -7.10      2.47      6.03  ...          10.53           2.20   \n2024-12-31     -3.73     -1.73     10.03  ...          10.00           1.50   \n\n            M0000609_lag4  M0000607_lag4  M0001428_lag4  M0000273_lag4  \\\nDate                                                                     \n2017-03-31         -13.94         -11.89          10.35          10.70   \n2017-06-30          -6.92          -6.33          10.23           9.00   \n2017-09-30          -4.16          -6.90          10.50           8.20   \n2017-12-31           2.49          -5.27          10.57           8.10   \n2018-03-31          25.30           6.55          10.20           9.20   \n2018-06-30          14.11           8.18          10.80           8.60   \n2018-09-30          14.82           6.38          10.27           7.50   \n2018-12-31          13.37           9.50           9.87           7.20   \n2019-03-31          19.68          17.06           9.90           7.50   \n2019-06-30          20.74          11.50           8.97           6.00   \n2019-09-30          20.66          11.67           9.00           5.40   \n2019-12-31           5.18           4.53           8.29           5.90   \n2020-03-31          -4.09           0.88           8.45           6.30   \n2020-06-30          -3.49          -1.01           8.53           5.80   \n2020-09-30          -6.20          -0.24           7.63           5.40   \n2020-12-31           3.85           1.98           7.73           5.40   \n2021-03-31          -2.15         -16.81         -18.15         -16.10   \n2021-06-30          -9.09          -0.09          -4.03          -3.10   \n2021-09-30           3.73           8.41           0.90           0.80   \n2021-12-31           5.66          16.50           4.63           2.90   \n2022-03-31          28.93          69.69          34.00          25.60   \n2022-06-30          44.51          30.37          14.07          12.60   \n2022-09-30          25.78          23.85           5.13           7.30   \n2022-12-31          23.68          22.90           3.50           4.90   \n2023-03-31          10.87          13.76           1.59           9.30   \n2023-06-30           1.01          11.02          -4.90           6.10   \n2023-09-30           0.07           8.91           3.53           5.90   \n2023-12-31          -6.66          -8.27          -2.73           5.10   \n2024-03-31          -6.28          -1.35           7.05           5.10   \n2024-06-30          -7.06          -4.28          11.40           3.80   \n2024-09-30          -8.53          -9.89           4.20           3.10   \n2024-12-31           0.92          -1.26           8.37           3.00   \n\n            M0001227_lag4  M0000612_lag4  M0000545_lag4  NPL_logit_lag4  \nDate                                                                     \n2017-03-31          -4.83           2.13           5.86           -5.63  \n2017-06-30          -2.93           2.08           6.07           -5.63  \n2017-09-30          -0.80           1.68           6.13           -5.63  \n2017-12-31           3.33           2.14           6.10           -5.63  \n2018-03-31           7.43           1.42           6.95           -5.63  \n2018-06-30           5.80           1.40           6.87           -5.32  \n2018-09-30           6.23           1.60           6.33           -5.14  \n2018-12-31           5.87           1.80           6.17           -4.64  \n2019-03-31           3.70           2.17           6.44           -4.19  \n2019-06-30           4.07           1.83           6.60           -3.74  \n2019-09-30           4.10           2.30           5.97           -3.72  \n2019-12-31           2.30           2.20           5.67           -3.64  \n2020-03-31           0.20           1.83           6.22           -3.37  \n2020-06-30           0.50           2.63           5.57           -3.35  \n2020-09-30          -0.77           2.87           5.00           -3.36  \n2020-12-31          -1.17           4.27           5.93           -3.37  \n2021-03-31          -0.60           4.97         -10.43           -3.40  \n2021-06-30          -3.27           2.73           4.37           -3.20  \n2021-09-30          -2.17           2.27           5.77           -3.30  \n2021-12-31          -1.33           0.07           7.07           -3.47  \n2022-03-31           2.13          -0.03          30.61           -3.56  \n2022-06-30           8.20           1.10           8.97           -3.68  \n2022-09-30           9.73           0.83           4.93           -3.86  \n2022-12-31          12.23           1.77           3.87           -3.82  \n2023-03-31           8.73           1.10           7.22           -3.47  \n2023-06-30           6.83           2.23           0.57           -3.26  \n2023-09-30           2.47           2.67           4.77           -3.27  \n2023-12-31          -1.10           1.83           2.83           -3.41  \n2024-03-31          -1.57           1.27           4.29           -3.44  \n2024-06-30          -4.53           0.10           4.50           -3.46  \n2024-09-30          -3.30          -0.07           4.23           -3.48  \n2024-12-31          -2.77          -0.33           6.00           -3.39  \n\n[32 rows x 80 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>NPL</th>\n      <th>M0000541</th>\n      <th>M0039354</th>\n      <th>M5650805</th>\n      <th>M5525763</th>\n      <th>M5525764</th>\n      <th>M0001385</th>\n      <th>M0001383</th>\n      <th>M0000609</th>\n      <th>M0000607</th>\n      <th>...</th>\n      <th>M0001385_lag4</th>\n      <th>M0001383_lag4</th>\n      <th>M0000609_lag4</th>\n      <th>M0000607_lag4</th>\n      <th>M0001428_lag4</th>\n      <th>M0000273_lag4</th>\n      <th>M0001227_lag4</th>\n      <th>M0000612_lag4</th>\n      <th>M0000545_lag4</th>\n      <th>NPL_logit_lag4</th>\n    </tr>\n    <tr>\n      <th>Date</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2017-03-31</th>\n      <td>0.00</td>\n      <td>7.00</td>\n      <td>7.00</td>\n      <td>5.01</td>\n      <td>16.17</td>\n      <td>12.78</td>\n      <td>10.40</td>\n      <td>18.23</td>\n      <td>25.30</td>\n      <td>6.55</td>\n      <td>...</td>\n      <td>13.57</td>\n      <td>19.37</td>\n      <td>-13.94</td>\n      <td>-11.89</td>\n      <td>10.35</td>\n      <td>10.70</td>\n      <td>-4.83</td>\n      <td>2.13</td>\n      <td>5.86</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2017-06-30</th>\n      <td>0.00</td>\n      <td>7.00</td>\n      <td>7.00</td>\n      <td>5.01</td>\n      <td>15.31</td>\n      <td>13.12</td>\n      <td>9.33</td>\n      <td>16.83</td>\n      <td>14.11</td>\n      <td>8.18</td>\n      <td>...</td>\n      <td>12.13</td>\n      <td>23.73</td>\n      <td>-6.92</td>\n      <td>-6.33</td>\n      <td>10.23</td>\n      <td>9.00</td>\n      <td>-2.93</td>\n      <td>2.08</td>\n      <td>6.07</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2017-09-30</th>\n      <td>0.01</td>\n      <td>7.00</td>\n      <td>6.90</td>\n      <td>5.01</td>\n      <td>15.18</td>\n      <td>13.61</td>\n      <td>8.83</td>\n      <td>14.43</td>\n      <td>14.82</td>\n      <td>6.38</td>\n      <td>...</td>\n      <td>11.03</td>\n      <td>25.13</td>\n      <td>-4.16</td>\n      <td>-6.90</td>\n      <td>10.50</td>\n      <td>8.20</td>\n      <td>-0.80</td>\n      <td>1.68</td>\n      <td>6.13</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2017-12-31</th>\n      <td>0.01</td>\n      <td>6.95</td>\n      <td>6.80</td>\n      <td>5.01</td>\n      <td>14.51</td>\n      <td>13.45</td>\n      <td>8.70</td>\n      <td>12.50</td>\n      <td>13.37</td>\n      <td>9.50</td>\n      <td>...</td>\n      <td>11.43</td>\n      <td>22.67</td>\n      <td>2.49</td>\n      <td>-5.27</td>\n      <td>10.57</td>\n      <td>8.10</td>\n      <td>3.33</td>\n      <td>2.14</td>\n      <td>6.10</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2018-03-31</th>\n      <td>0.01</td>\n      <td>6.90</td>\n      <td>6.90</td>\n      <td>5.01</td>\n      <td>13.17</td>\n      <td>13.07</td>\n      <td>8.53</td>\n      <td>10.20</td>\n      <td>19.68</td>\n      <td>17.06</td>\n      <td>...</td>\n      <td>10.40</td>\n      <td>18.23</td>\n      <td>25.30</td>\n      <td>6.55</td>\n      <td>10.20</td>\n      <td>9.20</td>\n      <td>7.43</td>\n      <td>1.42</td>\n      <td>6.95</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2018-06-30</th>\n      <td>0.02</td>\n      <td>6.90</td>\n      <td>6.90</td>\n      <td>4.83</td>\n      <td>12.20</td>\n      <td>12.71</td>\n      <td>8.20</td>\n      <td>6.60</td>\n      <td>20.74</td>\n      <td>11.50</td>\n      <td>...</td>\n      <td>9.33</td>\n      <td>16.83</td>\n      <td>14.11</td>\n      <td>8.18</td>\n      <td>10.80</td>\n      <td>8.60</td>\n      <td>5.80</td>\n      <td>1.40</td>\n      <td>6.87</td>\n      <td>-5.32</td>\n    </tr>\n    <tr>\n      <th>2018-09-30</th>\n      <td>0.02</td>\n      <td>6.80</td>\n      <td>6.70</td>\n      <td>5.00</td>\n      <td>11.40</td>\n      <td>12.95</td>\n      <td>8.33</td>\n      <td>4.33</td>\n      <td>20.66</td>\n      <td>11.67</td>\n      <td>...</td>\n      <td>8.83</td>\n      <td>14.43</td>\n      <td>14.82</td>\n      <td>6.38</td>\n      <td>10.27</td>\n      <td>7.50</td>\n      <td>6.23</td>\n      <td>1.60</td>\n      <td>6.33</td>\n      <td>-5.14</td>\n    </tr>\n    <tr>\n      <th>2018-12-31</th>\n      <td>0.03</td>\n      <td>6.75</td>\n      <td>6.50</td>\n      <td>4.87</td>\n      <td>10.45</td>\n      <td>13.02</td>\n      <td>8.03</td>\n      <td>1.90</td>\n      <td>5.18</td>\n      <td>4.53</td>\n      <td>...</td>\n      <td>8.70</td>\n      <td>12.50</td>\n      <td>13.37</td>\n      <td>9.50</td>\n      <td>9.87</td>\n      <td>7.20</td>\n      <td>5.87</td>\n      <td>1.80</td>\n      <td>6.17</td>\n      <td>-4.64</td>\n    </tr>\n    <tr>\n      <th>2019-03-31</th>\n      <td>0.03</td>\n      <td>6.30</td>\n      <td>6.30</td>\n      <td>5.20</td>\n      <td>10.89</td>\n      <td>13.57</td>\n      <td>8.33</td>\n      <td>2.33</td>\n      <td>-4.09</td>\n      <td>0.88</td>\n      <td>...</td>\n      <td>8.53</td>\n      <td>10.20</td>\n      <td>19.68</td>\n      <td>17.06</td>\n      <td>9.90</td>\n      <td>7.50</td>\n      <td>3.70</td>\n      <td>2.17</td>\n      <td>6.44</td>\n      <td>-4.19</td>\n    </tr>\n    <tr>\n      <th>2019-06-30</th>\n      <td>0.03</td>\n      <td>6.10</td>\n      <td>6.00</td>\n      <td>5.03</td>\n      <td>11.01</td>\n      <td>13.40</td>\n      <td>8.50</td>\n      <td>3.57</td>\n      <td>-3.49</td>\n      <td>-1.01</td>\n      <td>...</td>\n      <td>8.20</td>\n      <td>6.60</td>\n      <td>20.74</td>\n      <td>11.50</td>\n      <td>8.97</td>\n      <td>6.00</td>\n      <td>4.07</td>\n      <td>1.83</td>\n      <td>6.60</td>\n      <td>-3.74</td>\n    </tr>\n    <tr>\n      <th>2019-09-30</th>\n      <td>0.03</td>\n      <td>6.00</td>\n      <td>5.90</td>\n      <td>5.23</td>\n      <td>10.73</td>\n      <td>12.69</td>\n      <td>8.23</td>\n      <td>3.30</td>\n      <td>-6.20</td>\n      <td>-0.24</td>\n      <td>...</td>\n      <td>8.33</td>\n      <td>4.33</td>\n      <td>20.66</td>\n      <td>11.67</td>\n      <td>9.00</td>\n      <td>5.40</td>\n      <td>4.10</td>\n      <td>2.30</td>\n      <td>5.97</td>\n      <td>-3.72</td>\n    </tr>\n    <tr>\n      <th>2019-12-31</th>\n      <td>0.03</td>\n      <td>5.95</td>\n      <td>5.80</td>\n      <td>5.13</td>\n      <td>10.65</td>\n      <td>12.53</td>\n      <td>8.43</td>\n      <td>3.73</td>\n      <td>3.85</td>\n      <td>1.98</td>\n      <td>...</td>\n      <td>8.03</td>\n      <td>1.90</td>\n      <td>5.18</td>\n      <td>4.53</td>\n      <td>8.29</td>\n      <td>5.90</td>\n      <td>2.30</td>\n      <td>2.20</td>\n      <td>5.67</td>\n      <td>-3.64</td>\n    </tr>\n    <tr>\n      <th>2020-03-31</th>\n      <td>0.03</td>\n      <td>-6.90</td>\n      <td>-6.90</td>\n      <td>5.80</td>\n      <td>10.97</td>\n      <td>12.33</td>\n      <td>9.10</td>\n      <td>3.27</td>\n      <td>-2.15</td>\n      <td>-16.81</td>\n      <td>...</td>\n      <td>8.33</td>\n      <td>2.33</td>\n      <td>-4.09</td>\n      <td>0.88</td>\n      <td>8.45</td>\n      <td>6.30</td>\n      <td>0.20</td>\n      <td>1.83</td>\n      <td>6.22</td>\n      <td>-3.37</td>\n    </tr>\n    <tr>\n      <th>2020-06-30</th>\n      <td>0.04</td>\n      <td>-1.70</td>\n      <td>3.10</td>\n      <td>5.87</td>\n      <td>12.43</td>\n      <td>13.23</td>\n      <td>11.10</td>\n      <td>6.27</td>\n      <td>-9.09</td>\n      <td>-0.09</td>\n      <td>...</td>\n      <td>8.50</td>\n      <td>3.57</td>\n      <td>-3.49</td>\n      <td>-1.01</td>\n      <td>8.53</td>\n      <td>5.80</td>\n      <td>0.50</td>\n      <td>2.63</td>\n      <td>5.57</td>\n      <td>-3.35</td>\n    </tr>\n    <tr>\n      <th>2020-09-30</th>\n      <td>0.04</td>\n      <td>0.60</td>\n      <td>4.80</td>\n      <td>5.57</td>\n      <td>13.23</td>\n      <td>13.27</td>\n      <td>10.67</td>\n      <td>7.67</td>\n      <td>3.73</td>\n      <td>8.41</td>\n      <td>...</td>\n      <td>8.23</td>\n      <td>3.30</td>\n      <td>-6.20</td>\n      <td>-0.24</td>\n      <td>7.63</td>\n      <td>5.40</td>\n      <td>-0.77</td>\n      <td>2.87</td>\n      <td>5.00</td>\n      <td>-3.36</td>\n    </tr>\n    <tr>\n      <th>2020-12-31</th>\n      <td>0.03</td>\n      <td>2.24</td>\n      <td>6.40</td>\n      <td>5.23</td>\n      <td>13.53</td>\n      <td>13.27</td>\n      <td>10.43</td>\n      <td>9.23</td>\n      <td>5.66</td>\n      <td>16.50</td>\n      <td>...</td>\n      <td>8.43</td>\n      <td>3.73</td>\n      <td>3.85</td>\n      <td>1.98</td>\n      <td>7.73</td>\n      <td>5.40</td>\n      <td>-1.17</td>\n      <td>4.27</td>\n      <td>5.93</td>\n      <td>-3.37</td>\n    </tr>\n    <tr>\n      <th>2021-03-31</th>\n      <td>0.03</td>\n      <td>18.70</td>\n      <td>18.70</td>\n      <td>5.40</td>\n      <td>12.87</td>\n      <td>13.20</td>\n      <td>9.63</td>\n      <td>9.73</td>\n      <td>28.93</td>\n      <td>69.69</td>\n      <td>...</td>\n      <td>9.10</td>\n      <td>3.27</td>\n      <td>-2.15</td>\n      <td>-16.81</td>\n      <td>-18.15</td>\n      <td>-16.10</td>\n      <td>-0.60</td>\n      <td>4.97</td>\n      <td>-10.43</td>\n      <td>-3.40</td>\n    </tr>\n    <tr>\n      <th>2021-06-30</th>\n      <td>0.02</td>\n      <td>13.00</td>\n      <td>8.30</td>\n      <td>5.03</td>\n      <td>11.23</td>\n      <td>12.60</td>\n      <td>8.33</td>\n      <td>5.93</td>\n      <td>44.51</td>\n      <td>30.37</td>\n      <td>...</td>\n      <td>11.10</td>\n      <td>6.27</td>\n      <td>-9.09</td>\n      <td>-0.09</td>\n      <td>-4.03</td>\n      <td>-3.10</td>\n      <td>-3.27</td>\n      <td>2.73</td>\n      <td>4.37</td>\n      <td>-3.20</td>\n    </tr>\n    <tr>\n      <th>2021-09-30</th>\n      <td>0.02</td>\n      <td>10.10</td>\n      <td>5.20</td>\n      <td>5.03</td>\n      <td>10.33</td>\n      <td>12.20</td>\n      <td>8.27</td>\n      <td>4.27</td>\n      <td>25.78</td>\n      <td>23.85</td>\n      <td>...</td>\n      <td>10.67</td>\n      <td>7.67</td>\n      <td>3.73</td>\n      <td>8.41</td>\n      <td>0.90</td>\n      <td>0.80</td>\n      <td>-2.17</td>\n      <td>2.27</td>\n      <td>5.77</td>\n      <td>-3.30</td>\n    </tr>\n    <tr>\n      <th>2021-12-31</th>\n      <td>0.02</td>\n      <td>8.45</td>\n      <td>4.30</td>\n      <td>5.00</td>\n      <td>10.13</td>\n      <td>11.80</td>\n      <td>8.73</td>\n      <td>3.10</td>\n      <td>23.68</td>\n      <td>22.90</td>\n      <td>...</td>\n      <td>10.43</td>\n      <td>9.23</td>\n      <td>5.66</td>\n      <td>16.50</td>\n      <td>4.63</td>\n      <td>2.90</td>\n      <td>-1.33</td>\n      <td>0.07</td>\n      <td>7.07</td>\n      <td>-3.47</td>\n    </tr>\n    <tr>\n      <th>2022-03-31</th>\n      <td>0.03</td>\n      <td>4.80</td>\n      <td>4.80</td>\n      <td>5.53</td>\n      <td>10.40</td>\n      <td>11.37</td>\n      <td>9.57</td>\n      <td>2.50</td>\n      <td>10.87</td>\n      <td>13.76</td>\n      <td>...</td>\n      <td>9.63</td>\n      <td>9.73</td>\n      <td>28.93</td>\n      <td>69.69</td>\n      <td>34.00</td>\n      <td>25.60</td>\n      <td>2.13</td>\n      <td>-0.03</td>\n      <td>30.61</td>\n      <td>-3.56</td>\n    </tr>\n    <tr>\n      <th>2022-06-30</th>\n      <td>0.04</td>\n      <td>2.50</td>\n      <td>0.40</td>\n      <td>5.83</td>\n      <td>10.50</td>\n      <td>10.90</td>\n      <td>11.00</td>\n      <td>5.17</td>\n      <td>1.01</td>\n      <td>11.02</td>\n      <td>...</td>\n      <td>8.33</td>\n      <td>5.93</td>\n      <td>44.51</td>\n      <td>30.37</td>\n      <td>14.07</td>\n      <td>12.60</td>\n      <td>8.20</td>\n      <td>1.10</td>\n      <td>8.97</td>\n      <td>-3.68</td>\n    </tr>\n    <tr>\n      <th>2022-09-30</th>\n      <td>0.04</td>\n      <td>3.00</td>\n      <td>3.90</td>\n      <td>5.40</td>\n      <td>10.60</td>\n      <td>10.93</td>\n      <td>12.10</td>\n      <td>6.40</td>\n      <td>0.07</td>\n      <td>8.91</td>\n      <td>...</td>\n      <td>8.27</td>\n      <td>4.27</td>\n      <td>25.78</td>\n      <td>23.85</td>\n      <td>5.13</td>\n      <td>7.30</td>\n      <td>9.73</td>\n      <td>0.83</td>\n      <td>4.93</td>\n      <td>-3.86</td>\n    </tr>\n    <tr>\n      <th>2022-12-31</th>\n      <td>0.03</td>\n      <td>2.95</td>\n      <td>2.90</td>\n      <td>5.57</td>\n      <td>9.97</td>\n      <td>10.87</td>\n      <td>12.00</td>\n      <td>4.70</td>\n      <td>-6.66</td>\n      <td>-8.27</td>\n      <td>...</td>\n      <td>8.73</td>\n      <td>3.10</td>\n      <td>23.68</td>\n      <td>22.90</td>\n      <td>3.50</td>\n      <td>4.90</td>\n      <td>12.23</td>\n      <td>1.77</td>\n      <td>3.87</td>\n      <td>-3.82</td>\n    </tr>\n    <tr>\n      <th>2023-03-31</th>\n      <td>0.03</td>\n      <td>4.50</td>\n      <td>4.50</td>\n      <td>5.47</td>\n      <td>9.77</td>\n      <td>11.43</td>\n      <td>12.73</td>\n      <td>5.87</td>\n      <td>-6.28</td>\n      <td>-1.35</td>\n      <td>...</td>\n      <td>9.57</td>\n      <td>2.50</td>\n      <td>10.87</td>\n      <td>13.76</td>\n      <td>1.59</td>\n      <td>9.30</td>\n      <td>8.73</td>\n      <td>1.10</td>\n      <td>7.22</td>\n      <td>-3.47</td>\n    </tr>\n    <tr>\n      <th>2023-06-30</th>\n      <td>0.03</td>\n      <td>5.50</td>\n      <td>6.30</td>\n      <td>5.20</td>\n      <td>9.50</td>\n      <td>11.40</td>\n      <td>11.77</td>\n      <td>4.37</td>\n      <td>-7.06</td>\n      <td>-4.28</td>\n      <td>...</td>\n      <td>11.00</td>\n      <td>5.17</td>\n      <td>1.01</td>\n      <td>11.02</td>\n      <td>-4.90</td>\n      <td>6.10</td>\n      <td>6.83</td>\n      <td>2.23</td>\n      <td>0.57</td>\n      <td>-3.26</td>\n    </tr>\n    <tr>\n      <th>2023-09-30</th>\n      <td>0.03</td>\n      <td>5.20</td>\n      <td>4.90</td>\n      <td>5.17</td>\n      <td>8.97</td>\n      <td>10.87</td>\n      <td>10.53</td>\n      <td>2.20</td>\n      <td>-8.53</td>\n      <td>-9.89</td>\n      <td>...</td>\n      <td>12.10</td>\n      <td>6.40</td>\n      <td>0.07</td>\n      <td>8.91</td>\n      <td>3.53</td>\n      <td>5.90</td>\n      <td>2.47</td>\n      <td>2.67</td>\n      <td>4.77</td>\n      <td>-3.27</td>\n    </tr>\n    <tr>\n      <th>2023-12-31</th>\n      <td>0.03</td>\n      <td>5.25</td>\n      <td>5.20</td>\n      <td>5.03</td>\n      <td>9.40</td>\n      <td>10.60</td>\n      <td>10.00</td>\n      <td>1.50</td>\n      <td>0.92</td>\n      <td>-1.26</td>\n      <td>...</td>\n      <td>12.00</td>\n      <td>4.70</td>\n      <td>-6.66</td>\n      <td>-8.27</td>\n      <td>-2.73</td>\n      <td>5.10</td>\n      <td>-1.10</td>\n      <td>1.83</td>\n      <td>2.83</td>\n      <td>-3.41</td>\n    </tr>\n    <tr>\n      <th>2024-03-31</th>\n      <td>0.03</td>\n      <td>5.30</td>\n      <td>5.30</td>\n      <td>5.23</td>\n      <td>9.07</td>\n      <td>9.67</td>\n      <td>8.57</td>\n      <td>2.73</td>\n      <td>1.93</td>\n      <td>2.03</td>\n      <td>...</td>\n      <td>12.73</td>\n      <td>5.87</td>\n      <td>-6.28</td>\n      <td>-1.35</td>\n      <td>7.05</td>\n      <td>5.10</td>\n      <td>-1.57</td>\n      <td>1.27</td>\n      <td>4.29</td>\n      <td>-3.44</td>\n    </tr>\n    <tr>\n      <th>2024-06-30</th>\n      <td>0.03</td>\n      <td>5.00</td>\n      <td>4.70</td>\n      <td>5.00</td>\n      <td>8.27</td>\n      <td>8.77</td>\n      <td>6.80</td>\n      <td>-3.53</td>\n      <td>2.70</td>\n      <td>5.67</td>\n      <td>...</td>\n      <td>11.77</td>\n      <td>4.37</td>\n      <td>-7.06</td>\n      <td>-4.28</td>\n      <td>11.40</td>\n      <td>3.80</td>\n      <td>-4.53</td>\n      <td>0.10</td>\n      <td>4.50</td>\n      <td>-3.46</td>\n    </tr>\n    <tr>\n      <th>2024-09-30</th>\n      <td>0.03</td>\n      <td>4.80</td>\n      <td>4.60</td>\n      <td>5.20</td>\n      <td>8.10</td>\n      <td>8.07</td>\n      <td>6.47</td>\n      <td>-7.10</td>\n      <td>2.47</td>\n      <td>6.03</td>\n      <td>...</td>\n      <td>10.53</td>\n      <td>2.20</td>\n      <td>-8.53</td>\n      <td>-9.89</td>\n      <td>4.20</td>\n      <td>3.10</td>\n      <td>-3.30</td>\n      <td>-0.07</td>\n      <td>4.23</td>\n      <td>-3.48</td>\n    </tr>\n    <tr>\n      <th>2024-12-31</th>\n      <td>0.03</td>\n      <td>5.00</td>\n      <td>5.40</td>\n      <td>5.03</td>\n      <td>7.87</td>\n      <td>7.43</td>\n      <td>7.30</td>\n      <td>-3.73</td>\n      <td>-1.73</td>\n      <td>10.03</td>\n      <td>...</td>\n      <td>10.00</td>\n      <td>1.50</td>\n      <td>0.92</td>\n      <td>-1.26</td>\n      <td>8.37</td>\n      <td>3.00</td>\n      <td>-2.77</td>\n      <td>-0.33</td>\n      <td>6.00</td>\n      <td>-3.39</td>\n    </tr>\n  </tbody>\n</table>\n<p>32 rows × 80 columns</p>\n</div>"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 做一些简单的指标衍生\n",
    "data_shift1 = data_model_sample.shift(1)\n",
    "data_shift1.columns = [f'{x}_lag1' for x in data_shift1.columns]\n",
    "data_shift2 = data_model_sample.shift(2)\n",
    "data_shift2.columns = [f'{x}_lag2' for x in data_shift2.columns]\n",
    "data_shift3 = data_model_sample.shift(3)\n",
    "data_shift3.columns = [f'{x}_lag3' for x in data_shift3.columns]\n",
    "data_shift4 = data_model_sample.shift(4)\n",
    "data_shift4.columns = [f'{x}_lag4' for x in data_shift4.columns]\n",
    "data_train = pd.concat([data_model_sample, data_shift1, data_shift2, data_shift3, data_shift4], axis=1)\n",
    "data_train = data_train.ffill().bfill().loc['2017-01-01':]\n",
    "data_train.to_clipboard()\n",
    "data_train"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T08:46:36.285386Z",
     "start_time": "2025-03-06T08:46:36.191784Z"
    }
   },
   "id": "a8e1a1c211c72d8a",
   "execution_count": 8
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 单指标筛选"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "aeb49b8131ab339b"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "特征筛选完成，筛选前共78，筛选后共31个\n",
      "特征最低标准要求：\n",
      " - 缺失率不超过0.5\n",
      " - 连续缺失值不超过5个\n",
      " - 指标集中度不超过0.8\n",
      " - 单指标与目标指标相关系数不低于0.05\n",
      " - 单指标与目标指标之间的p值不超过0.05\n",
      " - 基准指标不在排除列表中\n"
     ]
    }
   ],
   "source": [
    "from rmtools.stats.stats import stats_avg_cv, stats_concn, stats_cmiss, stats_ycorr, stats_px_reg\n",
    "\n",
    "xs = [x for x in data_train.columns if x != 'NPL_logit' and x != 'NPL']\n",
    "y = 'NPL_logit'\n",
    "max_miss = 0.5  # 缺失率阈值\n",
    "max_cmiss = 5  # 连续缺失值阈值\n",
    "max_concn = 0.8  # 指标集中度阈值\n",
    "min_corr = 0.05  # 相关系数阈值\n",
    "max_pvalue = 0.05  # p值阈值\n",
    "\n",
    "data_basic = stats_avg_cv(data_train, xs)\n",
    "data_concn = stats_concn(data_train, xs)\n",
    "data_cmiss = stats_cmiss(data_train, xs)\n",
    "data_ycorr = stats_ycorr(data_train, xs, y, 'pearson')\n",
    "data_px = stats_px_reg(data_train, xs, y)\n",
    "\n",
    "data_stats = pd.concat([data_basic, data_concn, data_cmiss, data_ycorr, data_px], axis=1)\n",
    "data_stats['is_above_miss'] = data_stats['missing'] > max_miss  # 缺失率是否超过阈值\n",
    "data_stats['is_above_cmiss'] = data_stats['cmiss'] > max_cmiss  # 连续缺失值是否超过阈值\n",
    "data_stats['is_above_concn'] = data_stats['pvalue'] > max_concn  # 集中度是否超过阈值\n",
    "data_stats['is_below_corr'] = np.abs(data_stats['corr']) < min_corr  # 相关系数是否超过阈值\n",
    "data_stats['is_above_pvalue'] = data_stats['pvalue'] > max_pvalue  # p值是否超过阈值\n",
    "\n",
    "data_stats['is_selected'] = ~data_stats[['is_above_miss', 'is_above_cmiss', 'is_above_concn',\n",
    "                                         'is_below_corr', 'is_above_pvalue']].any(axis=1)\n",
    "list_kept_xs = data_stats.loc[data_stats['is_selected']].index.tolist()\n",
    "info_filter = (f\"特征筛选完成，筛选前共{len(xs)}，筛选后共{len(list_kept_xs)}个\\n\"\n",
    "               f\"特征最低标准要求：\\n\"\n",
    "               f\" - 缺失率不超过{max_miss}\\n\"\n",
    "               f\" - 连续缺失值不超过{max_cmiss}个\\n\"\n",
    "               f\" - 指标集中度不超过{max_concn}\\n\"\n",
    "               f\" - 单指标与目标指标相关系数不低于{min_corr}\\n\"\n",
    "               f\" - 单指标与目标指标之间的p值不超过{max_pvalue}\\n\"\n",
    "               f\" - 基准指标不在排除列表中\")\n",
    "print(info_filter)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-12T09:41:56.543545Z",
     "start_time": "2025-02-12T09:41:56.364526Z"
    }
   },
   "id": "52d6d3396e4bce62",
   "execution_count": 35
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 多指标组合筛选"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "19c5899a5ca19d5a"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "特征组合....: 100%|██████████| 206336/206336 [01:21<00:00, 2529.85it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "特征组合分析完成，筛选前共206336个组合，筛选后共2783个\n",
      "特征组合最低标准要求：\n",
      " - 指标组合相关系数不超过0.7\n",
      " - 指标组合vif不超过10\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "from rmtools.utils.gen_xslist import gen_xslist\n",
    "\n",
    "list_xs_comb = gen_xslist(xs=list_kept_xs, n_xs=range(2, 6))\n",
    "data_comb: pd.DataFrame = pd.DataFrame(columns=['xs', 'corr', 'vif'])\n",
    "data_base: pd.DataFrame = data_train.corr()\n",
    "\n",
    "max_corr: float = 0.7\n",
    "max_vif: float = 10\n",
    "\n",
    "for xs in tqdm(list_xs_comb, desc='特征组合....'):\n",
    "    _corr = stats_max_corr(data_base, xs, is_corrdata=True)\n",
    "    if _corr >= max_corr:\n",
    "        _vif = np.nan\n",
    "    else:\n",
    "        _vif = stats_max_vif(data_train, xs)\n",
    "        if _vif >= max_vif:\n",
    "            pass\n",
    "        else:\n",
    "            data_comb.loc[len(data_comb)] = [xs, _corr, _vif]\n",
    "\n",
    "data_comb['is_above_corr'] = data_comb['corr'] >= max_corr  # 相关系数是否超过阈值\n",
    "data_comb['is_above_vif'] = data_comb['vif'] >= max_vif  # vif是否超过阈值\n",
    "data_comb['is_selected'] = ~data_comb[['is_above_corr', 'is_above_vif']].any(axis=1)\n",
    "list_kept_xs_comb = data_comb.loc[data_comb['is_selected'], 'xs'].tolist()\n",
    "\n",
    "info_comb = (f\"特征组合分析完成，筛选前共{len(list_xs_comb)}个组合，筛选后共{len(list_kept_xs_comb)}个\\n\"\n",
    "             f\"特征组合最低标准要求：\\n\"\n",
    "             f\" - 指标组合相关系数不超过{max_corr}\\n\"\n",
    "             f\" - 指标组合vif不超过{max_vif}\")\n",
    "print(info_comb)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-12T08:15:36.475586Z",
     "start_time": "2025-02-12T08:14:14.659082Z"
    }
   },
   "id": "2256d18bb528f7fc",
   "execution_count": 10
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 模型训练"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "65b936d2df4b4efb"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "run model: 100%|██████████| 2783/2783 [00:10<00:00, 253.89it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "模型训练完成，共计训练2783个组合，筛选后共185个\n",
      "模型最低标准要求：\n",
      " - 模型p值不超过0.05\n",
      " - 指标p值不超过0.05\n",
      " - r2不低于0.4\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import mean_squared_error\n",
    "\n",
    "\n",
    "def one_model(indata: pd.DataFrame, xs: list[str], y: str):\n",
    "    x_sample = indata[xs].fillna(0)\n",
    "    x_sample = sm.add_constant(x_sample)\n",
    "    y_sample = indata[y]\n",
    "\n",
    "    model = sm.OLS(y_sample, x_sample, missing='drop')\n",
    "    model_fit = model.fit()\n",
    "    p_list = model_fit.pvalues.iloc[1:].to_dict()\n",
    "    p_value = model_fit.pvalues.iloc[1:].max()\n",
    "    p_model = model_fit.f_pvalue\n",
    "    r2 = model_fit.rsquared\n",
    "    mse = mean_squared_error(model_fit.predict(), y_sample)\n",
    "    coef = model_fit.params.to_dict()\n",
    "\n",
    "    dict_p = {f'p_{x}': y for x, y in p_list.items()}\n",
    "    dict_coef = {f'coef_{x}': y for x, y in coef.items()}\n",
    "    return model_fit, pd.DataFrame([{'xs': xs,\n",
    "                                     'p_value': p_value,\n",
    "                                     'p_model': p_model,\n",
    "                                     'r2': r2,\n",
    "                                     'mse_model': mse,\n",
    "                                     **dict_p,\n",
    "                                     **dict_coef}])\n",
    "\n",
    "\n",
    "def all_stats(indata: pd.DataFrame, y: str, list_xs: list[str]):\n",
    "    \"\"\" 所有统计指标 \"\"\"\n",
    "    data_stats = pd.DataFrame()\n",
    "    list_model = []\n",
    "    for xs in tqdm(list_xs, desc='run model'):\n",
    "        _model, _stat = one_model(indata, xs, y)\n",
    "        data_stats = pd.concat([data_stats, _stat], axis=0)\n",
    "        list_model.append(_model)\n",
    "\n",
    "    list_col1 = ['xs', 'p_value', 'p_model', 'r2', 'mse_model']\n",
    "    list_col2 = list(\n",
    "            set([x.removeprefix('coef_').removeprefix('p_') for x in data_stats.columns]).difference(set(list_col1)))\n",
    "    list_col2.sort()\n",
    "    list_col3 = list_col1 + ['coef_const']\n",
    "    for x in list_col2:\n",
    "        if x not in ['const', 'model', 'value']:\n",
    "            list_col3.extend([f'coef_{x}', f'p_{x}'])\n",
    "\n",
    "    data_stats = data_stats[list_col3]\n",
    "    data_stats.set_index('xs', inplace=True)\n",
    "    return data_stats, list_model\n",
    "\n",
    "\n",
    "max_pmodel = 0.05  # 模型p值阈值\n",
    "max_pvalue = 0.05  # 单指标p值阈值\n",
    "min_r2 = 0.4  # r2阈值\n",
    "\n",
    "# ols = all_stats(data_train, y, list_kept_xs_comb)\n",
    "data_models, list_models = all_stats(data_train, y, list_kept_xs_comb)\n",
    "data_models.insert(4, 'is_above_pvalue', data_models['p_value'] > max_pvalue)  # p值是否超过阈值\n",
    "data_models.insert(5, 'is_above_pmodel', data_models['p_model'] > max_pmodel)  # 模型p值是否超过阈值\n",
    "data_models.insert(6, 'is_below_r2', data_models['r2'] < min_r2)  # r2是否低于阈值\n",
    "data_models.insert(7, 'is_qualified',\n",
    "                   ~data_models[['is_above_pvalue', 'is_above_pmodel', 'is_below_r2']].any(axis=1))\n",
    "info_models = (f\"模型训练完成，共计训练{len(list_models)}个组合，筛选后共{data_models['is_qualified'].sum()}个\\n\"\n",
    "               f\"模型最低标准要求：\\n\"\n",
    "               f\" - 模型p值不超过{max_pmodel}\\n\"\n",
    "               f\" - 指标p值不超过{max_pvalue}\\n\"\n",
    "               f\" - r2不低于{min_r2}\")\n",
    "print(info_models)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-12T08:28:35.870192Z",
     "start_time": "2025-02-12T08:28:24.862827Z"
    }
   },
   "id": "84a6d26ab0c08b07",
   "execution_count": 21
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "                                                    p_value  p_model   r2  \\\nxs                                                                          \n[M5650805, M0001383]                                   0.00     0.00 0.71   \n[M5650805, M0001383_lag1]                              0.01     0.00 0.74   \n[M5525763, NPL_lag1]                                   0.01     0.00 0.85   \n[M5525763, M0001428_lag1]                              0.02     0.00 0.61   \n[M5525763, NPL_lag2]                                   0.01     0.00 0.74   \n...                                                     ...      ...  ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...     0.03     0.00 0.79   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...     0.02     0.00 0.81   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...     0.04     0.00 0.79   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...     0.03     0.00 0.88   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...     0.04     0.00 0.91   \n\n                                                    mse_model  \\\nxs                                                              \n[M5650805, M0001383]                                     0.11   \n[M5650805, M0001383_lag1]                                0.09   \n[M5525763, NPL_lag1]                                     0.05   \n[M5525763, M0001428_lag1]                                0.14   \n[M5525763, NPL_lag2]                                     0.10   \n...                                                       ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...       0.08   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...       0.07   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...       0.08   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...       0.04   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...       0.03   \n\n                                                    is_above_pvalue  \\\nxs                                                                    \n[M5650805, M0001383]                                          False   \n[M5650805, M0001383_lag1]                                     False   \n[M5525763, NPL_lag1]                                          False   \n[M5525763, M0001428_lag1]                                     False   \n[M5525763, NPL_lag2]                                          False   \n...                                                             ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...            False   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...            False   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...            False   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...            False   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...            False   \n\n                                                    is_above_pmodel  \\\nxs                                                                    \n[M5650805, M0001383]                                          False   \n[M5650805, M0001383_lag1]                                     False   \n[M5525763, NPL_lag1]                                          False   \n[M5525763, M0001428_lag1]                                     False   \n[M5525763, NPL_lag2]                                          False   \n...                                                             ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...            False   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...            False   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...            False   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...            False   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...            False   \n\n                                                    is_below_r2  is_qualified  \\\nxs                                                                              \n[M5650805, M0001383]                                      False          True   \n[M5650805, M0001383_lag1]                                 False          True   \n[M5525763, NPL_lag1]                                      False          True   \n[M5525763, M0001428_lag1]                                 False          True   \n[M5525763, NPL_lag2]                                      False          True   \n...                                                         ...           ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...        False          True   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...        False          True   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...        False          True   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...        False          True   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...        False          True   \n\n                                                    coef_const  \\\nxs                                                               \n[M5650805, M0001383]                                     -8.03   \n[M5650805, M0001383_lag1]                                -6.13   \n[M5525763, NPL_lag1]                                     -4.05   \n[M5525763, M0001428_lag1]                                -1.32   \n[M5525763, NPL_lag2]                                     -3.44   \n...                                                        ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...       -5.44   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...       -5.35   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...       -5.33   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...       -2.19   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...       -2.44   \n\n                                                    coef_M0000607_lag4  ...  \\\nxs                                                                      ...   \n[M5650805, M0001383]                                               NaN  ...   \n[M5650805, M0001383_lag1]                                          NaN  ...   \n[M5525763, NPL_lag1]                                               NaN  ...   \n[M5525763, M0001428_lag1]                                          NaN  ...   \n[M5525763, NPL_lag2]                                               NaN  ...   \n...                                                                ...  ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...                0.01  ...   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                0.02  ...   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                0.02  ...   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...                0.02  ...   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...                0.01  ...   \n\n                                                    coef_NPL_lag4  p_NPL_lag4  \\\nxs                                                                              \n[M5650805, M0001383]                                          NaN         NaN   \n[M5650805, M0001383_lag1]                                     NaN         NaN   \n[M5525763, NPL_lag1]                                          NaN         NaN   \n[M5525763, M0001428_lag1]                                     NaN         NaN   \n[M5525763, NPL_lag2]                                          NaN         NaN   \n...                                                           ...         ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...          26.83        0.00   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...            NaN         NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...            NaN         NaN   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...            NaN         NaN   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...            NaN         NaN   \n\n                                                    coef_NPL_logit_lag1  \\\nxs                                                                        \n[M5650805, M0001383]                                                NaN   \n[M5650805, M0001383_lag1]                                           NaN   \n[M5525763, NPL_lag1]                                                NaN   \n[M5525763, M0001428_lag1]                                           NaN   \n[M5525763, NPL_lag2]                                                NaN   \n...                                                                 ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...                  NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                  NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                  NaN   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...                  NaN   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...                  NaN   \n\n                                                    p_NPL_logit_lag1  \\\nxs                                                                     \n[M5650805, M0001383]                                             NaN   \n[M5650805, M0001383_lag1]                                        NaN   \n[M5525763, NPL_lag1]                                             NaN   \n[M5525763, M0001428_lag1]                                        NaN   \n[M5525763, NPL_lag2]                                             NaN   \n...                                                              ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...               NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...               NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...               NaN   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...               NaN   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...               NaN   \n\n                                                    coef_NPL_logit_lag2  \\\nxs                                                                        \n[M5650805, M0001383]                                                NaN   \n[M5650805, M0001383_lag1]                                           NaN   \n[M5525763, NPL_lag1]                                                NaN   \n[M5525763, M0001428_lag1]                                           NaN   \n[M5525763, NPL_lag2]                                                NaN   \n...                                                                 ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...                  NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                  NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                  NaN   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...                  NaN   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...                  NaN   \n\n                                                    p_NPL_logit_lag2  \\\nxs                                                                     \n[M5650805, M0001383]                                             NaN   \n[M5650805, M0001383_lag1]                                        NaN   \n[M5525763, NPL_lag1]                                             NaN   \n[M5525763, M0001428_lag1]                                        NaN   \n[M5525763, NPL_lag2]                                             NaN   \n...                                                              ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...               NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...               NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...               NaN   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...               NaN   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...               NaN   \n\n                                                    coef_NPL_logit_lag3  \\\nxs                                                                        \n[M5650805, M0001383]                                                NaN   \n[M5650805, M0001383_lag1]                                           NaN   \n[M5525763, NPL_lag1]                                                NaN   \n[M5525763, M0001428_lag1]                                           NaN   \n[M5525763, NPL_lag2]                                                NaN   \n...                                                                 ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...                  NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                  NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                  NaN   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...                  NaN   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...                  NaN   \n\n                                                    p_NPL_logit_lag3  \\\nxs                                                                     \n[M5650805, M0001383]                                             NaN   \n[M5650805, M0001383_lag1]                                        NaN   \n[M5525763, NPL_lag1]                                             NaN   \n[M5525763, M0001428_lag1]                                        NaN   \n[M5525763, NPL_lag2]                                             NaN   \n...                                                              ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...               NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...               NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...               NaN   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...               NaN   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...               NaN   \n\n                                                    coef_NPL_logit_lag4  \\\nxs                                                                        \n[M5650805, M0001383]                                                NaN   \n[M5650805, M0001383_lag1]                                           NaN   \n[M5525763, NPL_lag1]                                                NaN   \n[M5525763, M0001428_lag1]                                           NaN   \n[M5525763, NPL_lag2]                                                NaN   \n...                                                                 ...   \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...                  NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                  NaN   \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...                  NaN   \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...                  NaN   \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...                  NaN   \n\n                                                    p_NPL_logit_lag4  \nxs                                                                    \n[M5650805, M0001383]                                             NaN  \n[M5650805, M0001383_lag1]                                        NaN  \n[M5525763, NPL_lag1]                                             NaN  \n[M5525763, M0001428_lag1]                                        NaN  \n[M5525763, NPL_lag2]                                             NaN  \n...                                                              ...  \n[M0001383, M0000609_lag1, NPL_lag4, M5525763_la...               NaN  \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...               NaN  \n[M0001383, M0001428_lag1, M0001227_lag1, M55257...               NaN  \n[M0000609, M0001383_lag1, M0001227_lag1, M00013...               NaN  \n[M0000609, M0001227_lag1, M0001383_lag2, M00013...               NaN  \n\n[177 rows x 69 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>p_value</th>\n      <th>p_model</th>\n      <th>r2</th>\n      <th>mse_model</th>\n      <th>is_above_pvalue</th>\n      <th>is_above_pmodel</th>\n      <th>is_below_r2</th>\n      <th>is_qualified</th>\n      <th>coef_const</th>\n      <th>coef_M0000607_lag4</th>\n      <th>...</th>\n      <th>coef_NPL_lag4</th>\n      <th>p_NPL_lag4</th>\n      <th>coef_NPL_logit_lag1</th>\n      <th>p_NPL_logit_lag1</th>\n      <th>coef_NPL_logit_lag2</th>\n      <th>p_NPL_logit_lag2</th>\n      <th>coef_NPL_logit_lag3</th>\n      <th>p_NPL_logit_lag3</th>\n      <th>coef_NPL_logit_lag4</th>\n      <th>p_NPL_logit_lag4</th>\n    </tr>\n    <tr>\n      <th>xs</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>[M5650805, M0001383]</th>\n      <td>0.00</td>\n      <td>0.00</td>\n      <td>0.71</td>\n      <td>0.11</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-8.03</td>\n      <td>NaN</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>[M5650805, M0001383_lag1]</th>\n      <td>0.01</td>\n      <td>0.00</td>\n      <td>0.74</td>\n      <td>0.09</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-6.13</td>\n      <td>NaN</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>[M5525763, NPL_lag1]</th>\n      <td>0.01</td>\n      <td>0.00</td>\n      <td>0.85</td>\n      <td>0.05</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-4.05</td>\n      <td>NaN</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>[M5525763, M0001428_lag1]</th>\n      <td>0.02</td>\n      <td>0.00</td>\n      <td>0.61</td>\n      <td>0.14</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-1.32</td>\n      <td>NaN</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>[M5525763, NPL_lag2]</th>\n      <td>0.01</td>\n      <td>0.00</td>\n      <td>0.74</td>\n      <td>0.10</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-3.44</td>\n      <td>NaN</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>[M0001383, M0000609_lag1, NPL_lag4, M5525763_lag4, M0000607_lag4]</th>\n      <td>0.03</td>\n      <td>0.00</td>\n      <td>0.79</td>\n      <td>0.08</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-5.44</td>\n      <td>0.01</td>\n      <td>...</td>\n      <td>26.83</td>\n      <td>0.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>[M0001383, M0001428_lag1, M0001227_lag1, M5525764_lag2, M0000607_lag4]</th>\n      <td>0.02</td>\n      <td>0.00</td>\n      <td>0.81</td>\n      <td>0.07</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-5.35</td>\n      <td>0.02</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>[M0001383, M0001428_lag1, M0001227_lag1, M5525764_lag3, M0000607_lag4]</th>\n      <td>0.04</td>\n      <td>0.00</td>\n      <td>0.79</td>\n      <td>0.08</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-5.33</td>\n      <td>0.02</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>[M0000609, M0001383_lag1, M0001227_lag1, M0001385_lag4, M0000607_lag4]</th>\n      <td>0.03</td>\n      <td>0.00</td>\n      <td>0.88</td>\n      <td>0.04</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-2.19</td>\n      <td>0.02</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>[M0000609, M0001227_lag1, M0001383_lag2, M0001385_lag4, M0000607_lag4]</th>\n      <td>0.04</td>\n      <td>0.00</td>\n      <td>0.91</td>\n      <td>0.03</td>\n      <td>False</td>\n      <td>False</td>\n      <td>False</td>\n      <td>True</td>\n      <td>-2.44</td>\n      <td>0.01</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n  </tbody>\n</table>\n<p>177 rows × 69 columns</p>\n</div>"
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# data_models_qualified = data_models[\n",
    "#     ~data_models.index.astype(str).str.contains('NPL_lag') & data_models['is_qualified']]\n",
    "# data_models_qualified = data_models_qualified[\n",
    "#     data_models_qualified.index.astype(str).str.count('_lag') <= data_models_qualified.index.astype(str).str.count(',')]\n",
    "\n",
    "data_models_qualified = data_models[data_models['is_qualified']]\n",
    "\n",
    "\n",
    "def _is_sml(xlist: list[str]) -> bool:\n",
    "    newset = [x.split('_lag')[0] for x in xlist]\n",
    "    return len(set(newset)) == len(xlist)\n",
    "\n",
    "\n",
    "data_models_qualified = data_models_qualified[data_models_qualified.index.map(lambda x: _is_sml(x))]\n",
    "data_models_qualified.dropna(axis=1, how='all', inplace=True)\n",
    "data_models_qualified.to_clipboard()\n",
    "data_models_qualified"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-12T08:30:05.063271Z",
     "start_time": "2025-02-12T08:30:04.996399Z"
    }
   },
   "id": "830e7c1f62979c10",
   "execution_count": 23
  },
  {
   "cell_type": "markdown",
   "source": [
    "模型预测"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "dc7dae63e190c4fc"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "           Unnamed: 0  M0039354  M0000541  M0000545  M0000273  M0001428  \\\n2025-03-31    预测值【基准】      5.00      5.00      5.00      3.70      5.60   \n2025-06-30        NaN      5.17      5.10      5.60      4.20      8.40   \n2025-09-30        NaN      4.90      5.10      4.80      4.60      4.90   \n2025-12-31        NaN      4.70      4.60      5.20      4.75      5.10   \n2025-03-31    预测值【乐观】      8.59      9.18     10.53      9.67     13.61   \n2025-06-30        NaN      8.76      9.28     11.13     10.17     16.41   \n2025-09-30        NaN      8.49      9.28     10.33     10.57     12.91   \n2025-12-31        NaN      8.29      8.78     10.73     10.72     13.11   \n2025-03-31    预测值【悲观】      1.41      0.82     -0.53     -2.27     -2.41   \n2025-06-30        NaN      1.58      0.92      0.07     -1.77      0.39   \n2025-09-30        NaN      1.31      0.92     -0.73     -1.37     -3.11   \n2025-12-31        NaN      1.11      0.42     -0.33     -1.22     -2.91   \n\n            M0000609  M0000607  M0000612  M0001227  M0001383  M0001385  \\\n2025-03-31      1.70      3.25      0.20     -1.80     -3.73      6.80   \n2025-06-30     -2.80      2.40      0.40     -1.40     -3.73      8.30   \n2025-09-30      4.10      2.20      0.10     -0.50     -3.73      8.30   \n2025-12-31      0.10     -3.60      0.80      1.50     -3.73      8.50   \n2025-03-31     14.89     18.16      1.45      2.71      1.65      8.36   \n2025-06-30     10.39     17.31      1.65      3.11      1.65      9.86   \n2025-09-30     17.29     17.11      1.35      4.01      1.65      9.86   \n2025-12-31     13.29     11.31      2.05      6.01      1.65     10.06   \n2025-03-31    -11.49    -11.66     -1.05     -6.31     -9.12      5.24   \n2025-06-30    -15.99    -12.51     -0.85     -5.91     -9.12      6.74   \n2025-09-30     -9.09    -12.71     -1.15     -5.01     -9.12      6.74   \n2025-12-31    -13.09    -18.51     -0.45     -3.01     -9.12      6.94   \n\n            M5525764  M5525763  M5650805  \n2025-03-31      7.80      8.30      5.40  \n2025-06-30      8.20      9.10      5.40  \n2025-09-30      8.40      9.10      5.40  \n2025-12-31      8.20      8.87      5.40  \n2025-03-31      9.43     10.43      5.12  \n2025-06-30      9.83     11.23      5.12  \n2025-09-30     10.03     11.23      5.12  \n2025-12-31      9.83     11.00      5.68  \n2025-03-31      6.17      6.17      5.68  \n2025-06-30      6.57      6.97      5.68  \n2025-09-30      6.77      6.97      5.68  \n2025-12-31      6.57      6.74      5.68  ",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>Unnamed: 0</th>\n      <th>M0039354</th>\n      <th>M0000541</th>\n      <th>M0000545</th>\n      <th>M0000273</th>\n      <th>M0001428</th>\n      <th>M0000609</th>\n      <th>M0000607</th>\n      <th>M0000612</th>\n      <th>M0001227</th>\n      <th>M0001383</th>\n      <th>M0001385</th>\n      <th>M5525764</th>\n      <th>M5525763</th>\n      <th>M5650805</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2025-03-31</th>\n      <td>预测值【基准】</td>\n      <td>5.00</td>\n      <td>5.00</td>\n      <td>5.00</td>\n      <td>3.70</td>\n      <td>5.60</td>\n      <td>1.70</td>\n      <td>3.25</td>\n      <td>0.20</td>\n      <td>-1.80</td>\n      <td>-3.73</td>\n      <td>6.80</td>\n      <td>7.80</td>\n      <td>8.30</td>\n      <td>5.40</td>\n    </tr>\n    <tr>\n      <th>2025-06-30</th>\n      <td>NaN</td>\n      <td>5.17</td>\n      <td>5.10</td>\n      <td>5.60</td>\n      <td>4.20</td>\n      <td>8.40</td>\n      <td>-2.80</td>\n      <td>2.40</td>\n      <td>0.40</td>\n      <td>-1.40</td>\n      <td>-3.73</td>\n      <td>8.30</td>\n      <td>8.20</td>\n      <td>9.10</td>\n      <td>5.40</td>\n    </tr>\n    <tr>\n      <th>2025-09-30</th>\n      <td>NaN</td>\n      <td>4.90</td>\n      <td>5.10</td>\n      <td>4.80</td>\n      <td>4.60</td>\n      <td>4.90</td>\n      <td>4.10</td>\n      <td>2.20</td>\n      <td>0.10</td>\n      <td>-0.50</td>\n      <td>-3.73</td>\n      <td>8.30</td>\n      <td>8.40</td>\n      <td>9.10</td>\n      <td>5.40</td>\n    </tr>\n    <tr>\n      <th>2025-12-31</th>\n      <td>NaN</td>\n      <td>4.70</td>\n      <td>4.60</td>\n      <td>5.20</td>\n      <td>4.75</td>\n      <td>5.10</td>\n      <td>0.10</td>\n      <td>-3.60</td>\n      <td>0.80</td>\n      <td>1.50</td>\n      <td>-3.73</td>\n      <td>8.50</td>\n      <td>8.20</td>\n      <td>8.87</td>\n      <td>5.40</td>\n    </tr>\n    <tr>\n      <th>2025-03-31</th>\n      <td>预测值【乐观】</td>\n      <td>8.59</td>\n      <td>9.18</td>\n      <td>10.53</td>\n      <td>9.67</td>\n      <td>13.61</td>\n      <td>14.89</td>\n      <td>18.16</td>\n      <td>1.45</td>\n      <td>2.71</td>\n      <td>1.65</td>\n      <td>8.36</td>\n      <td>9.43</td>\n      <td>10.43</td>\n      <td>5.12</td>\n    </tr>\n    <tr>\n      <th>2025-06-30</th>\n      <td>NaN</td>\n      <td>8.76</td>\n      <td>9.28</td>\n      <td>11.13</td>\n      <td>10.17</td>\n      <td>16.41</td>\n      <td>10.39</td>\n      <td>17.31</td>\n      <td>1.65</td>\n      <td>3.11</td>\n      <td>1.65</td>\n      <td>9.86</td>\n      <td>9.83</td>\n      <td>11.23</td>\n      <td>5.12</td>\n    </tr>\n    <tr>\n      <th>2025-09-30</th>\n      <td>NaN</td>\n      <td>8.49</td>\n      <td>9.28</td>\n      <td>10.33</td>\n      <td>10.57</td>\n      <td>12.91</td>\n      <td>17.29</td>\n      <td>17.11</td>\n      <td>1.35</td>\n      <td>4.01</td>\n      <td>1.65</td>\n      <td>9.86</td>\n      <td>10.03</td>\n      <td>11.23</td>\n      <td>5.12</td>\n    </tr>\n    <tr>\n      <th>2025-12-31</th>\n      <td>NaN</td>\n      <td>8.29</td>\n      <td>8.78</td>\n      <td>10.73</td>\n      <td>10.72</td>\n      <td>13.11</td>\n      <td>13.29</td>\n      <td>11.31</td>\n      <td>2.05</td>\n      <td>6.01</td>\n      <td>1.65</td>\n      <td>10.06</td>\n      <td>9.83</td>\n      <td>11.00</td>\n      <td>5.68</td>\n    </tr>\n    <tr>\n      <th>2025-03-31</th>\n      <td>预测值【悲观】</td>\n      <td>1.41</td>\n      <td>0.82</td>\n      <td>-0.53</td>\n      <td>-2.27</td>\n      <td>-2.41</td>\n      <td>-11.49</td>\n      <td>-11.66</td>\n      <td>-1.05</td>\n      <td>-6.31</td>\n      <td>-9.12</td>\n      <td>5.24</td>\n      <td>6.17</td>\n      <td>6.17</td>\n      <td>5.68</td>\n    </tr>\n    <tr>\n      <th>2025-06-30</th>\n      <td>NaN</td>\n      <td>1.58</td>\n      <td>0.92</td>\n      <td>0.07</td>\n      <td>-1.77</td>\n      <td>0.39</td>\n      <td>-15.99</td>\n      <td>-12.51</td>\n      <td>-0.85</td>\n      <td>-5.91</td>\n      <td>-9.12</td>\n      <td>6.74</td>\n      <td>6.57</td>\n      <td>6.97</td>\n      <td>5.68</td>\n    </tr>\n    <tr>\n      <th>2025-09-30</th>\n      <td>NaN</td>\n      <td>1.31</td>\n      <td>0.92</td>\n      <td>-0.73</td>\n      <td>-1.37</td>\n      <td>-3.11</td>\n      <td>-9.09</td>\n      <td>-12.71</td>\n      <td>-1.15</td>\n      <td>-5.01</td>\n      <td>-9.12</td>\n      <td>6.74</td>\n      <td>6.77</td>\n      <td>6.97</td>\n      <td>5.68</td>\n    </tr>\n    <tr>\n      <th>2025-12-31</th>\n      <td>NaN</td>\n      <td>1.11</td>\n      <td>0.42</td>\n      <td>-0.33</td>\n      <td>-1.22</td>\n      <td>-2.91</td>\n      <td>-13.09</td>\n      <td>-18.51</td>\n      <td>-0.45</td>\n      <td>-3.01</td>\n      <td>-9.12</td>\n      <td>6.94</td>\n      <td>6.57</td>\n      <td>6.74</td>\n      <td>5.68</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_fwd = pd.read_excel(file_path, sheet_name='前瞻估计', index_col=1, header=3)\n",
    "data_fwd"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-12T09:36:47.414997Z",
     "start_time": "2025-02-12T09:36:47.299643Z"
    }
   },
   "id": "6971d5dd4e2f6ef0",
   "execution_count": 27
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "            M0039354  M0000541  M0000545  M0000273  M0001428  M0000609  \\\n2025-03-31      8.59      9.18     10.53      9.67     13.61     14.89   \n2025-06-30      8.76      9.28     11.13     10.17     16.41     10.39   \n2025-09-30      8.49      9.28     10.33     10.57     12.91     17.29   \n2025-12-31      8.29      8.78     10.73     10.72     13.11     13.29   \n\n            M0000607  M0000612  M0001227  M0001383  M0001385  M5525764  \\\n2025-03-31     18.16      1.45      2.71      1.65      8.36      9.43   \n2025-06-30     17.31      1.65      3.11      1.65      9.86      9.83   \n2025-09-30     17.11      1.35      4.01      1.65      9.86     10.03   \n2025-12-31     11.31      2.05      6.01      1.65     10.06      9.83   \n\n            M5525763  M5650805  \n2025-03-31     10.43      5.12  \n2025-06-30     11.23      5.12  \n2025-09-30     11.23      5.12  \n2025-12-31     11.00      5.68  ",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>M0039354</th>\n      <th>M0000541</th>\n      <th>M0000545</th>\n      <th>M0000273</th>\n      <th>M0001428</th>\n      <th>M0000609</th>\n      <th>M0000607</th>\n      <th>M0000612</th>\n      <th>M0001227</th>\n      <th>M0001383</th>\n      <th>M0001385</th>\n      <th>M5525764</th>\n      <th>M5525763</th>\n      <th>M5650805</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2025-03-31</th>\n      <td>8.59</td>\n      <td>9.18</td>\n      <td>10.53</td>\n      <td>9.67</td>\n      <td>13.61</td>\n      <td>14.89</td>\n      <td>18.16</td>\n      <td>1.45</td>\n      <td>2.71</td>\n      <td>1.65</td>\n      <td>8.36</td>\n      <td>9.43</td>\n      <td>10.43</td>\n      <td>5.12</td>\n    </tr>\n    <tr>\n      <th>2025-06-30</th>\n      <td>8.76</td>\n      <td>9.28</td>\n      <td>11.13</td>\n      <td>10.17</td>\n      <td>16.41</td>\n      <td>10.39</td>\n      <td>17.31</td>\n      <td>1.65</td>\n      <td>3.11</td>\n      <td>1.65</td>\n      <td>9.86</td>\n      <td>9.83</td>\n      <td>11.23</td>\n      <td>5.12</td>\n    </tr>\n    <tr>\n      <th>2025-09-30</th>\n      <td>8.49</td>\n      <td>9.28</td>\n      <td>10.33</td>\n      <td>10.57</td>\n      <td>12.91</td>\n      <td>17.29</td>\n      <td>17.11</td>\n      <td>1.35</td>\n      <td>4.01</td>\n      <td>1.65</td>\n      <td>9.86</td>\n      <td>10.03</td>\n      <td>11.23</td>\n      <td>5.12</td>\n    </tr>\n    <tr>\n      <th>2025-12-31</th>\n      <td>8.29</td>\n      <td>8.78</td>\n      <td>10.73</td>\n      <td>10.72</td>\n      <td>13.11</td>\n      <td>13.29</td>\n      <td>11.31</td>\n      <td>2.05</td>\n      <td>6.01</td>\n      <td>1.65</td>\n      <td>10.06</td>\n      <td>9.83</td>\n      <td>11.00</td>\n      <td>5.68</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_fwd_base = data_fwd.iloc[4:8, 1:]\n",
    "data_fwd_base"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-12T09:42:18.623069Z",
     "start_time": "2025-02-12T09:42:18.614396Z"
    }
   },
   "id": "cf3b667017f11742",
   "execution_count": 36
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "def _gendata(data_in):\n",
    "    data_in['NPL_logit'] = np.log(data_in['NPL'] / (1 - data_in['NPL']))\n",
    "    data_shift1 = data_in.shift(1)\n",
    "    data_shift1.columns = [f'{x}_lag1' for x in data_shift1.columns]\n",
    "    data_shift2 = data_in.shift(2)\n",
    "    data_shift2.columns = [f'{x}_lag2' for x in data_shift2.columns]\n",
    "    data_shift3 = data_in.shift(3)\n",
    "    data_shift3.columns = [f'{x}_lag3' for x in data_shift3.columns]\n",
    "    data_shift4 = data_in.shift(4)\n",
    "    data_shift4.columns = [f'{x}_lag4' for x in data_shift4.columns]\n",
    "    data_train = pd.concat([data_in, data_shift1, data_shift2, data_shift3, data_shift4], axis=1)\n",
    "\n",
    "    return data_train\n",
    "\n",
    "\n",
    "def _stress_data(senr: int = 0):\n",
    "    data_ = data_fwd.iloc[4 * senr:4 * (senr + 1), 1:]\n",
    "    data_stress = pd.concat([data_train[[x for x in data_train.columns if '_lag' not in x]], data_])\n",
    "    return _gendata(data_stress).loc['2024-01-01':]\n",
    "\n",
    "\n",
    "def _get_coef(model_ver: int):\n",
    "    xvars = data_models_qualified.index[model_ver]\n",
    "    coefs = data_models_qualified.iloc[model_ver][[f'coef_{x}' for x in xvars]]\n",
    "    const = data_models_qualified.iloc[model_ver]['coef_const']\n",
    "    return xvars, coefs, const\n",
    "\n",
    "\n",
    "def _stress_result(ver: int = 0):\n",
    "    xvars, coefs, const = _get_coef(ver)\n",
    "\n",
    "    xvars2 = list(set(xvars).union({'NPL_lag1', 'NPL_lag2', 'NPL_lag3', 'NPL_lag4',\n",
    "                                    'NPL_logit_lag1', 'NPL_logit_lag2', 'NPL_logit_lag3', 'NPL_logit_lag4'}))\n",
    "\n",
    "    data_result = pd.DataFrame()\n",
    "    for i in range(3):\n",
    "        data_stress = _stress_data(senr=i)[xvars2]\n",
    "        data_stress = data_stress.loc[:, ~data_stress.columns.duplicated()]\n",
    "        data_stress['NPL_logit_pred'] = data_stress[xvars].dot(coefs.values) + const\n",
    "\n",
    "        for _ in range(4):\n",
    "            data_stress['NPL_logit_lag1'] = data_stress['NPL_logit_lag1'].combine_first(\n",
    "                    data_stress['NPL_logit_pred'].shift(1)).astype(float)\n",
    "            data_stress['NPL_logit_lag2'] = data_stress['NPL_logit_lag2'].combine_first(\n",
    "                    data_stress['NPL_logit_pred'].shift(2)).astype(float)\n",
    "            data_stress['NPL_logit_lag3'] = data_stress['NPL_logit_lag3'].combine_first(\n",
    "                    data_stress['NPL_logit_pred'].shift(3)).astype(float)\n",
    "            data_stress['NPL_logit_lag4'] = data_stress['NPL_logit_lag4'].combine_first(\n",
    "                    data_stress['NPL_logit_pred'].shift(4)).astype(float)\n",
    "            data_stress['NPL_lag1'] = np.exp(data_stress['NPL_logit_lag1']) / (\n",
    "                    1 + np.exp(data_stress['NPL_logit_lag1']))\n",
    "            data_stress['NPL_lag2'] = np.exp(data_stress['NPL_logit_lag2']) / (\n",
    "                    1 + np.exp(data_stress['NPL_logit_lag2']))\n",
    "            data_stress['NPL_lag3'] = np.exp(data_stress['NPL_logit_lag3']) / (\n",
    "                    1 + np.exp(data_stress['NPL_logit_lag3']))\n",
    "            data_stress['NPL_lag4'] = np.exp(data_stress['NPL_logit_lag4']) / (\n",
    "                    1 + np.exp(data_stress['NPL_logit_lag4']))\n",
    "\n",
    "            data_stress['NPL_logit_pred'] = (data_stress[xvars].dot(coefs.values) + const).astype(float)\n",
    "\n",
    "        data_stress[f'NPL_logit_{i}'] = data_stress['NPL_logit_pred']\n",
    "        data_stress[f'NPL_pred_{i}'] = np.exp(data_stress[f'NPL_logit_{i}']) / (\n",
    "                1 + np.exp(data_stress[f'NPL_logit_{i}']))\n",
    "        if i == 0:\n",
    "            data_result = data_stress[[f'NPL_logit_{i}', f'NPL_pred_{i}']].copy()\n",
    "        else:\n",
    "            data_result = pd.concat([data_result, data_stress[[f'NPL_logit_{i}', f'NPL_pred_{i}']]], axis=1)\n",
    "    return data_result"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-12T10:56:51.090653Z",
     "start_time": "2025-02-12T10:56:51.079623Z"
    }
   },
   "id": "b51124c024f8435f",
   "execution_count": 93
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "      0     1    2     3    4     5    6     7    8     9   ...    39   40  \\\n0      0 -3.50 0.03 -3.50 0.03 -3.50 0.03 -3.21 0.04 -3.21  ... -3.52 0.03   \n1      1 -3.35 0.03 -3.35 0.03 -3.35 0.03 -3.58 0.03 -3.58  ... -3.42 0.03   \n2      2 -3.27 0.04 -3.27 0.04 -3.27 0.04 -3.33 0.03 -3.33  ... -3.82 0.02   \n3      3 -3.33 0.03 -3.33 0.03 -3.33 0.03 -3.08 0.04 -3.08  ... -3.94 0.02   \n4      4 -3.35 0.03 -3.35 0.03 -3.35 0.03 -3.18 0.04 -3.18  ... -3.61 0.03   \n..   ...   ...  ...   ...  ...   ...  ...   ...  ...   ...  ...   ...  ...   \n172  172 -3.58 0.03 -3.58 0.03 -3.58 0.03 -3.34 0.03 -3.34  ... -3.91 0.02   \n173  173 -3.62 0.03 -3.62 0.03 -3.62 0.03 -3.19 0.04 -3.19  ... -4.22 0.01   \n174  174 -3.53 0.03 -3.53 0.03 -3.53 0.03 -3.22 0.04 -3.22  ... -4.58 0.01   \n175  175 -3.65 0.03 -3.65 0.03 -3.65 0.03 -3.65 0.03 -3.65  ... -3.04 0.05   \n176  176 -3.54 0.03 -3.54 0.03 -3.54 0.03 -3.45 0.03 -3.45  ... -3.04 0.05   \n\n       41   42    43   44    45   46    47   48  \n0   -2.14 0.10 -2.83 0.06 -3.01 0.05 -2.14 0.10  \n1   -2.27 0.09 -2.85 0.05 -3.11 0.04 -2.27 0.09  \n2   -2.51 0.08 -3.07 0.04 -3.89 0.02 -1.23 0.23  \n3   -2.74 0.06 -3.22 0.04 -3.82 0.02 -2.61 0.07  \n4   -2.73 0.06 -3.31 0.04 -3.70 0.02 -2.87 0.05  \n..    ...  ...   ...  ...   ...  ...   ...  ...  \n172 -2.83 0.06 -3.54 0.03 -4.08 0.02 -3.00 0.05  \n173 -3.05 0.05 -3.49 0.03 -4.08 0.02 -2.91 0.05  \n174 -2.88 0.05 -3.60 0.03 -4.18 0.02 -3.03 0.05  \n175 -2.06 0.11 -2.70 0.06 -3.19 0.04 -2.21 0.10  \n176 -2.13 0.11 -2.68 0.06 -3.14 0.04 -2.23 0.10  \n\n[177 rows x 49 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>0</th>\n      <th>1</th>\n      <th>2</th>\n      <th>3</th>\n      <th>4</th>\n      <th>5</th>\n      <th>6</th>\n      <th>7</th>\n      <th>8</th>\n      <th>9</th>\n      <th>...</th>\n      <th>39</th>\n      <th>40</th>\n      <th>41</th>\n      <th>42</th>\n      <th>43</th>\n      <th>44</th>\n      <th>45</th>\n      <th>46</th>\n      <th>47</th>\n      <th>48</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>0</td>\n      <td>-3.50</td>\n      <td>0.03</td>\n      <td>-3.50</td>\n      <td>0.03</td>\n      <td>-3.50</td>\n      <td>0.03</td>\n      <td>-3.21</td>\n      <td>0.04</td>\n      <td>-3.21</td>\n      <td>...</td>\n      <td>-3.52</td>\n      <td>0.03</td>\n      <td>-2.14</td>\n      <td>0.10</td>\n      <td>-2.83</td>\n      <td>0.06</td>\n      <td>-3.01</td>\n      <td>0.05</td>\n      <td>-2.14</td>\n      <td>0.10</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>1</td>\n      <td>-3.35</td>\n      <td>0.03</td>\n      <td>-3.35</td>\n      <td>0.03</td>\n      <td>-3.35</td>\n      <td>0.03</td>\n      <td>-3.58</td>\n      <td>0.03</td>\n      <td>-3.58</td>\n      <td>...</td>\n      <td>-3.42</td>\n      <td>0.03</td>\n      <td>-2.27</td>\n      <td>0.09</td>\n      <td>-2.85</td>\n      <td>0.05</td>\n      <td>-3.11</td>\n      <td>0.04</td>\n      <td>-2.27</td>\n      <td>0.09</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2</td>\n      <td>-3.27</td>\n      <td>0.04</td>\n      <td>-3.27</td>\n      <td>0.04</td>\n      <td>-3.27</td>\n      <td>0.04</td>\n      <td>-3.33</td>\n      <td>0.03</td>\n      <td>-3.33</td>\n      <td>...</td>\n      <td>-3.82</td>\n      <td>0.02</td>\n      <td>-2.51</td>\n      <td>0.08</td>\n      <td>-3.07</td>\n      <td>0.04</td>\n      <td>-3.89</td>\n      <td>0.02</td>\n      <td>-1.23</td>\n      <td>0.23</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>3</td>\n      <td>-3.33</td>\n      <td>0.03</td>\n      <td>-3.33</td>\n      <td>0.03</td>\n      <td>-3.33</td>\n      <td>0.03</td>\n      <td>-3.08</td>\n      <td>0.04</td>\n      <td>-3.08</td>\n      <td>...</td>\n      <td>-3.94</td>\n      <td>0.02</td>\n      <td>-2.74</td>\n      <td>0.06</td>\n      <td>-3.22</td>\n      <td>0.04</td>\n      <td>-3.82</td>\n      <td>0.02</td>\n      <td>-2.61</td>\n      <td>0.07</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>4</td>\n      <td>-3.35</td>\n      <td>0.03</td>\n      <td>-3.35</td>\n      <td>0.03</td>\n      <td>-3.35</td>\n      <td>0.03</td>\n      <td>-3.18</td>\n      <td>0.04</td>\n      <td>-3.18</td>\n      <td>...</td>\n      <td>-3.61</td>\n      <td>0.03</td>\n      <td>-2.73</td>\n      <td>0.06</td>\n      <td>-3.31</td>\n      <td>0.04</td>\n      <td>-3.70</td>\n      <td>0.02</td>\n      <td>-2.87</td>\n      <td>0.05</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>172</th>\n      <td>172</td>\n      <td>-3.58</td>\n      <td>0.03</td>\n      <td>-3.58</td>\n      <td>0.03</td>\n      <td>-3.58</td>\n      <td>0.03</td>\n      <td>-3.34</td>\n      <td>0.03</td>\n      <td>-3.34</td>\n      <td>...</td>\n      <td>-3.91</td>\n      <td>0.02</td>\n      <td>-2.83</td>\n      <td>0.06</td>\n      <td>-3.54</td>\n      <td>0.03</td>\n      <td>-4.08</td>\n      <td>0.02</td>\n      <td>-3.00</td>\n      <td>0.05</td>\n    </tr>\n    <tr>\n      <th>173</th>\n      <td>173</td>\n      <td>-3.62</td>\n      <td>0.03</td>\n      <td>-3.62</td>\n      <td>0.03</td>\n      <td>-3.62</td>\n      <td>0.03</td>\n      <td>-3.19</td>\n      <td>0.04</td>\n      <td>-3.19</td>\n      <td>...</td>\n      <td>-4.22</td>\n      <td>0.01</td>\n      <td>-3.05</td>\n      <td>0.05</td>\n      <td>-3.49</td>\n      <td>0.03</td>\n      <td>-4.08</td>\n      <td>0.02</td>\n      <td>-2.91</td>\n      <td>0.05</td>\n    </tr>\n    <tr>\n      <th>174</th>\n      <td>174</td>\n      <td>-3.53</td>\n      <td>0.03</td>\n      <td>-3.53</td>\n      <td>0.03</td>\n      <td>-3.53</td>\n      <td>0.03</td>\n      <td>-3.22</td>\n      <td>0.04</td>\n      <td>-3.22</td>\n      <td>...</td>\n      <td>-4.58</td>\n      <td>0.01</td>\n      <td>-2.88</td>\n      <td>0.05</td>\n      <td>-3.60</td>\n      <td>0.03</td>\n      <td>-4.18</td>\n      <td>0.02</td>\n      <td>-3.03</td>\n      <td>0.05</td>\n    </tr>\n    <tr>\n      <th>175</th>\n      <td>175</td>\n      <td>-3.65</td>\n      <td>0.03</td>\n      <td>-3.65</td>\n      <td>0.03</td>\n      <td>-3.65</td>\n      <td>0.03</td>\n      <td>-3.65</td>\n      <td>0.03</td>\n      <td>-3.65</td>\n      <td>...</td>\n      <td>-3.04</td>\n      <td>0.05</td>\n      <td>-2.06</td>\n      <td>0.11</td>\n      <td>-2.70</td>\n      <td>0.06</td>\n      <td>-3.19</td>\n      <td>0.04</td>\n      <td>-2.21</td>\n      <td>0.10</td>\n    </tr>\n    <tr>\n      <th>176</th>\n      <td>176</td>\n      <td>-3.54</td>\n      <td>0.03</td>\n      <td>-3.54</td>\n      <td>0.03</td>\n      <td>-3.54</td>\n      <td>0.03</td>\n      <td>-3.45</td>\n      <td>0.03</td>\n      <td>-3.45</td>\n      <td>...</td>\n      <td>-3.04</td>\n      <td>0.05</td>\n      <td>-2.13</td>\n      <td>0.11</td>\n      <td>-2.68</td>\n      <td>0.06</td>\n      <td>-3.14</td>\n      <td>0.04</td>\n      <td>-2.23</td>\n      <td>0.10</td>\n    </tr>\n  </tbody>\n</table>\n<p>177 rows × 49 columns</p>\n</div>"
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list_rst = []\n",
    "for i in range(len(data_models_qualified)):\n",
    "    data_rst = _stress_result(i).stack().to_frame().T.values.tolist()\n",
    "    list_rst.append([i] + data_rst[0])\n",
    "\n",
    "data_stress_summary = pd.DataFrame(list_rst)\n",
    "data_stress_summary.to_clipboard(index=False)\n",
    "data_stress_summary"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-12T10:57:37.511479Z",
     "start_time": "2025-02-12T10:57:29.788951Z"
    }
   },
   "id": "cda9872ea73ba6b8",
   "execution_count": 95
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "data_train.loc['2024-12-31':, ['NPL', 'NPL_logit']].to_clipboard()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-12T10:51:27.924420Z",
     "start_time": "2025-02-12T10:51:27.858366Z"
    }
   },
   "id": "251a9d2029ff81a4",
   "execution_count": 84
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 额外的测试"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "9c859ca05a44e339"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "xs = ['M0001227', 'M5525763_lag1', 'M0000607_lag4']\n",
    "y = 'NPL_logit'\n",
    "x_sample = data_train[xs].fillna(0)\n",
    "x_sample = sm.add_constant(x_sample)\n",
    "y_sample = data_train[y]\n",
    "\n",
    "model = sm.OLS(y_sample, x_sample, missing='drop')\n",
    "model_fit = model.fit()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T08:48:41.225745Z",
     "start_time": "2025-03-06T08:48:41.204492Z"
    }
   },
   "id": "841a89914beff998",
   "execution_count": 10
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "<class 'statsmodels.iolib.summary.Summary'>\n\"\"\"\n                            OLS Regression Results                            \n==============================================================================\nDep. Variable:              NPL_logit   R-squared:                       0.611\nModel:                            OLS   Adj. R-squared:                  0.570\nMethod:                 Least Squares   F-statistic:                     14.67\nDate:                Thu, 06 Mar 2025   Prob (F-statistic):           6.24e-06\nTime:                        16:48:51   Log-Likelihood:                -14.047\nNo. Observations:                  32   AIC:                             36.09\nDf Residuals:                      28   BIC:                             41.96\nDf Model:                           3                                         \nCovariance Type:            nonrobust                                         \n=================================================================================\n                    coef    std err          t      P>|t|      [0.025      0.975]\n---------------------------------------------------------------------------------\nconst            -2.3916      0.509     -4.702      0.000      -3.433      -1.350\nM0001227         -0.0572      0.020     -2.823      0.009      -0.099      -0.016\nM5525763_lag1    -0.1153      0.045     -2.580      0.015      -0.207      -0.024\nM0000607_lag4     0.0139      0.005      2.619      0.014       0.003       0.025\n==============================================================================\nOmnibus:                        6.595   Durbin-Watson:                   0.481\nProb(Omnibus):                  0.037   Jarque-Bera (JB):                5.086\nSkew:                          -0.730   Prob(JB):                       0.0786\nKurtosis:                       4.297   Cond. No.                         128.\n==============================================================================\n\nNotes:\n[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n\"\"\"",
      "text/html": "<table class=\"simpletable\">\n<caption>OLS Regression Results</caption>\n<tr>\n  <th>Dep. Variable:</th>        <td>NPL_logit</td>    <th>  R-squared:         </th> <td>   0.611</td>\n</tr>\n<tr>\n  <th>Model:</th>                   <td>OLS</td>       <th>  Adj. R-squared:    </th> <td>   0.570</td>\n</tr>\n<tr>\n  <th>Method:</th>             <td>Least Squares</td>  <th>  F-statistic:       </th> <td>   14.67</td>\n</tr>\n<tr>\n  <th>Date:</th>             <td>Thu, 06 Mar 2025</td> <th>  Prob (F-statistic):</th> <td>6.24e-06</td>\n</tr>\n<tr>\n  <th>Time:</th>                 <td>16:48:51</td>     <th>  Log-Likelihood:    </th> <td> -14.047</td>\n</tr>\n<tr>\n  <th>No. Observations:</th>      <td>    32</td>      <th>  AIC:               </th> <td>   36.09</td>\n</tr>\n<tr>\n  <th>Df Residuals:</th>          <td>    28</td>      <th>  BIC:               </th> <td>   41.96</td>\n</tr>\n<tr>\n  <th>Df Model:</th>              <td>     3</td>      <th>                     </th>     <td> </td>   \n</tr>\n<tr>\n  <th>Covariance Type:</th>      <td>nonrobust</td>    <th>                     </th>     <td> </td>   \n</tr>\n</table>\n<table class=\"simpletable\">\n<tr>\n        <td></td>           <th>coef</th>     <th>std err</th>      <th>t</th>      <th>P>|t|</th>  <th>[0.025</th>    <th>0.975]</th>  \n</tr>\n<tr>\n  <th>const</th>         <td>   -2.3916</td> <td>    0.509</td> <td>   -4.702</td> <td> 0.000</td> <td>   -3.433</td> <td>   -1.350</td>\n</tr>\n<tr>\n  <th>M0001227</th>      <td>   -0.0572</td> <td>    0.020</td> <td>   -2.823</td> <td> 0.009</td> <td>   -0.099</td> <td>   -0.016</td>\n</tr>\n<tr>\n  <th>M5525763_lag1</th> <td>   -0.1153</td> <td>    0.045</td> <td>   -2.580</td> <td> 0.015</td> <td>   -0.207</td> <td>   -0.024</td>\n</tr>\n<tr>\n  <th>M0000607_lag4</th> <td>    0.0139</td> <td>    0.005</td> <td>    2.619</td> <td> 0.014</td> <td>    0.003</td> <td>    0.025</td>\n</tr>\n</table>\n<table class=\"simpletable\">\n<tr>\n  <th>Omnibus:</th>       <td> 6.595</td> <th>  Durbin-Watson:     </th> <td>   0.481</td>\n</tr>\n<tr>\n  <th>Prob(Omnibus):</th> <td> 0.037</td> <th>  Jarque-Bera (JB):  </th> <td>   5.086</td>\n</tr>\n<tr>\n  <th>Skew:</th>          <td>-0.730</td> <th>  Prob(JB):          </th> <td>  0.0786</td>\n</tr>\n<tr>\n  <th>Kurtosis:</th>      <td> 4.297</td> <th>  Cond. No.          </th> <td>    128.</td>\n</tr>\n</table><br/><br/>Notes:<br/>[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.",
      "text/latex": "\\begin{center}\n\\begin{tabular}{lclc}\n\\toprule\n\\textbf{Dep. Variable:}    &    NPL\\_logit    & \\textbf{  R-squared:         } &     0.611   \\\\\n\\textbf{Model:}            &       OLS        & \\textbf{  Adj. R-squared:    } &     0.570   \\\\\n\\textbf{Method:}           &  Least Squares   & \\textbf{  F-statistic:       } &     14.67   \\\\\n\\textbf{Date:}             & Thu, 06 Mar 2025 & \\textbf{  Prob (F-statistic):} &  6.24e-06   \\\\\n\\textbf{Time:}             &     16:48:51     & \\textbf{  Log-Likelihood:    } &   -14.047   \\\\\n\\textbf{No. Observations:} &          32      & \\textbf{  AIC:               } &     36.09   \\\\\n\\textbf{Df Residuals:}     &          28      & \\textbf{  BIC:               } &     41.96   \\\\\n\\textbf{Df Model:}         &           3      & \\textbf{                     } &             \\\\\n\\textbf{Covariance Type:}  &    nonrobust     & \\textbf{                     } &             \\\\\n\\bottomrule\n\\end{tabular}\n\\begin{tabular}{lcccccc}\n                        & \\textbf{coef} & \\textbf{std err} & \\textbf{t} & \\textbf{P$> |$t$|$} & \\textbf{[0.025} & \\textbf{0.975]}  \\\\\n\\midrule\n\\textbf{const}          &      -2.3916  &        0.509     &    -4.702  &         0.000        &       -3.433    &       -1.350     \\\\\n\\textbf{M0001227}       &      -0.0572  &        0.020     &    -2.823  &         0.009        &       -0.099    &       -0.016     \\\\\n\\textbf{M5525763\\_lag1} &      -0.1153  &        0.045     &    -2.580  &         0.015        &       -0.207    &       -0.024     \\\\\n\\textbf{M0000607\\_lag4} &       0.0139  &        0.005     &     2.619  &         0.014        &        0.003    &        0.025     \\\\\n\\bottomrule\n\\end{tabular}\n\\begin{tabular}{lclc}\n\\textbf{Omnibus:}       &  6.595 & \\textbf{  Durbin-Watson:     } &    0.481  \\\\\n\\textbf{Prob(Omnibus):} &  0.037 & \\textbf{  Jarque-Bera (JB):  } &    5.086  \\\\\n\\textbf{Skew:}          & -0.730 & \\textbf{  Prob(JB):          } &   0.0786  \\\\\n\\textbf{Kurtosis:}      &  4.297 & \\textbf{  Cond. No.          } &     128.  \\\\\n\\bottomrule\n\\end{tabular}\n%\\caption{OLS Regression Results}\n\\end{center}\n\nNotes: \\newline\n [1] Standard Errors assume that the covariance matrix of the errors is correctly specified."
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model_fit.summary()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T08:48:51.294808Z",
     "start_time": "2025-03-06T08:48:51.266615Z"
    }
   },
   "id": "2622bf8f61f253e9",
   "execution_count": 11
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "VIF检验结果:\n",
      " [['M0001227', 1.3477053159579007], ['M5525763_lag1', 1.3183267876434064], ['M0000607_lag4', 1.2055630737196497]]\n"
     ]
    }
   ],
   "source": [
    "from statsmodels.stats.outliers_influence import variance_inflation_factor\n",
    "\n",
    "x_sample = np.array(data_train[xs])\n",
    "list_vif = []\n",
    "for i in range(x_sample.shape[1]):\n",
    "    vif_ = variance_inflation_factor(x_sample, i)\n",
    "    list_vif.append([xs[i], vif_])\n",
    "\n",
    "print('VIF检验结果:\\n', list_vif)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T09:11:30.717243Z",
     "start_time": "2025-03-06T09:11:30.703482Z"
    }
   },
   "id": "eb23c334c477ab8b",
   "execution_count": 15
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
